I have a console application using Rx.NET.
I need to block until an IConnectableObservable has completed, for which I am using IConnectableObservable.Wait()
.
When an unhandled exception is thrown, it is swallowed and the application hangs. I want the application to crash, and the stack track to be printed to the console.
I do not want to add an OnError
handler to my IConnectableObserver
because this loses the original stack trace.
I have tried using the .Wait()
method on the unpublished observable, but this re-subscribes which causes undesirable behaviour.
I have tried using .GetAwaiter().GetResult()
instead, but this has the same problem.
var connectable = myObservable.Publish();
connectable.Subscribe(myObserver1);
connectable.Subscribe(myObserver2);
connectable.Connect();
connectcable.Wait();
How can I wait for an IConnectableObservable to complete while retaining typical unhandled exception behaviour?
There's some misdirection in the chain of events here. The error isn't being swallowed - far from it, it's being re-thrown.
The usual suspects are some weird concurrency and scheduling issues, but nobody suspects the Subscribe
method.
When you call Subscribe
with something other than your own IObserver<T>
, you're creating an AnonymousObserver
with these default actions.
new AnonymousObserver<T>(Ignore, Throw, Nop)
which is effectively
new AnonymousObserver<T>(_ => {}, exn => throw exn, () => {})
The default error handler will throw the error on whatever context you're observing on. Yikes. Sometimes it might be the AppDomain timer, or on a pooled thread, and since it can't be handled, your application goes down.
So if we change the sample to provide in a dummy handler,
var myObservable = Observable.Interval(TimeSpan.FromMilliseconds(100)).Take(4).Concat(Observable.Throw(new Exception(), 1L));
var connectable = myObservable.Publish();
connectable.Subscribe(Console.WriteLine, exn => Console.WriteLine("Handled"));
connectable.Subscribe(Console.WriteLine, exn => Console.WriteLine("Handled"));
connectable.Connect();
try
{
connectable.Wait();
}
catch (Exception)
{
Console.WriteLine("An error, but I'm safe");
}
You can handle the error in the Wait
like you'd expect to.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.