I have the following scenario. A Task that generates events and might throw an exception:
public event EventHandler<EventArgs> MyEvent;
new Task(() =>
{
while (condition)
{
// Generate standard .NET event.
MyEvent(this, new EventArgs());
// Maybe throw exception.
if (somethingIsWrong) throw new Exception();
}
});
All pretty straightforward. I listen to the events using Observable.FromEvent:
var events =
Observable.FromEvent<EventArgs>(h => myClass.MyEvent += h,
h => myClass.MyEvent -= h);
events.Subscribe(
ev => DoSomethingOnNext(ev),
ex => DoSomethingOnError(ex),
() => DoSomethingOnCompleted());
This all works fine when no exception occurs. When an exception is thrown by the task, however, I’d like to know this in my observable. The exception is now ‘hidden’ inside the task.
Can I only do this by creating another event when the exception takes place, wrapping it inside an IObservable and subscribing to this new observable? Or is there a simpler way?
How about this:
The output is:
DoSomethingOnNext:System.Collections.Generic.Event
1[System.EventArgs]1[System.EventArgs]DoSomethingOnNext:System.Collections.Generic.Event
DoSomethingOnNext:System.Collections.Generic.Event
1[System.EventArgs]1[System.EventArgs]DoSomethingOnNext:System.Collections.Generic.Event
DoSomethingOnNext:System.Collections.Generic.Event`1[System.EventArgs]
DoSomethingOnError:System.AggregateException: One or more errors occurred. —> System.Exception: Exception of type ‘System.Exception’ was thrown.
at RxDisposeTests.Program.<>c_DisplayClass9.b_0() in C:\Users\Richard.Hein\Documents\Visual Studio 2010\Projects\RxConsole\RxDisposeTests\Program.cs:line 25
at System.Threading.Tasks.Task.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
— End of inner exception stack trace —
—> (Inner Exception #0) System.Exception: Exception of type ‘System.Exception’ was thrown.
at RxDisposeTests.Program.<>c_DisplayClass9.b_0() in C:\Users\Richard.Hein\Documents\Visual Studio 2010\Projects\RxConsole\RxDisposeTests\Program.cs:line 25
at System.Threading.Tasks.Task.InnerInvoke()
at System.Threading.Tasks.Task.Execute()<—
EDIT:
Not sure if TakeUntil is a good solution, because Task might return something other than Exceptions, right? So this could work: