dotnet / reactive

The Reactive Extensions for .NET
http://reactivex.io
MIT License
6.73k stars 751 forks source link

Default OnError is unobserved Task for WPF #1654

Open magla42 opened 3 years ago

magla42 commented 3 years ago

Running Rx 5.0.0 in a new WPF application targeting .NET 6 in VS2022/Windows 10.

I would expect the following code snippet, running on the UI thread, to cause an unhandled exception (divide by zero) and crash the application on the third event:

Observable.Range(1, 5)
    .Select(x => Task.Run(() => x / (x - 3)))
    .Concat()
    .Subscribe(x => Debug.WriteLine($"OnNext: {x}"));

The observer stops after two events as expected, but no unhandled exception surfaces and the application continues.

Looking at unobserved task exceptions, like this:

TaskScheduler.UnobservedTaskException += (_, e) =>
    {
        MessageBox.Show(e.Exception.InnerException?.Message, "Unobserved task exception");
    };

reveals that the exception is (re)thrown on an unobserved task (when the finalizer feels like running that is, which for me at least happens in debug mode).

So it seems that Rx (Concat?) does not observe the task used to run the OnError method per default for a WPF application in this case. I am guessing this is a bug?

If I do for example this,

Observable.Range(1, 5)
    .Select(x => Task.Run(() => x / (x - 3)))
    .Concat()
    .ObserveOnDispatcher()
    .Subscribe(x => Debug.WriteLine($"OnNext: {x}"));

or

Observable.Range(1, 5)
    .Select(x => Task.Run(() => x / (x - 3)))
    .Concat()
    .ObserveOn(ThreadPoolScheduler.Instance)
    .Subscribe(x => Debug.WriteLine($"OnNext: {x}"));

the application crashes due to an unhandled exception, as expected.

theodorzoulias commented 2 years ago

Might be related to this: Async Create hanging while publishing observable