我有以下情况。生成事件并可能抛出异常的Task
:
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();
}
});
一切都很简单。我使用Observable.FromEvent
收听事件:
var events =
Observable.FromEvent<EventArgs>(h => myClass.MyEvent += h,
h => myClass.MyEvent -= h);
events.Subscribe(
ev => DoSomethingOnNext(ev),
ex => DoSomethingOnError(ex),
() => DoSomethingOnCompleted());
当没有异常发生时,这一切都正常。但是,当任务抛出异常时,我想在我的观察中知道这一点。该异常现在在任务中“隐藏”。
我是否可以通过在发生异常时创建另一个事件,将其包装在IObservable
内并订阅此新的observable来实现此目的?或者有更简单的方法吗?
答案 0 :(得分:2)
这个怎么样:
class Program
{
public event EventHandler<EventArgs> MyEvent;
static void Main(string[] args)
{
var myClass = new Program();
var task = new Task(() =>
{
for(var i=0; i<5; i++) {
// Generate standard .NET event.
myClass.MyEvent(myClass, new EventArgs());
}
throw new Exception();
});
var obsTask = task.ToObservable();
var events = Observable.FromEvent<EventArgs>(h => myClass.MyEvent += h, h => myClass.MyEvent -= h);
events.TakeUntil(obsTask).Subscribe(
ev => DoSomethingOnNext(ev),
ex => DoSomethingOnError(ex),
() => DoSomethingOnCompleted());
task.Start();
Console.ReadKey();
}
private static void DoSomethingOnCompleted()
{
Console.WriteLine("DoSomethingOnCompleted");
}
private static void DoSomethingOnError(Exception ex)
{
Console.WriteLine("DoSomethingOnError:" + ex.ToString());
}
private static void DoSomethingOnNext(IEvent<EventArgs> ev)
{
Console.WriteLine("DoSomethingOnNext:" + ev.ToString());
}
输出结果为:
DoSomethingOnNext:System.Collections.Generic.Event 1[System.EventArgs]
DoSomethingOnNext:System.Collections.Generic.Event
1 [System.EventArgs]
DoSomethingOnNext:System.Collections.Generic.Event 1[System.EventArgs]
DoSomethingOnNext:System.Collections.Generic.Event
1 [System.EventArgs]
DoSomethingOnNext:System.Collections.Generic.Event`1 [System.EventArgs]
DoSomethingOnError:System.AggregateException:发生一个或多个错误。 ---&GT; System.Exception:抛出了类型'System.Exception'的异常。
在RxDisposeTests.Program。&lt;&gt; c_ DisplayClass9.b _0()在C:\ Users \ Richard.Hein \ Documents \ Visual Studio 2010 \ Projects \ RxConsole \ RxDisposeTests \ Program.cs:line 25
在System.Threading.Tasks.Task.InnerInvoke()
在System.Threading.Tasks.Task.Execute()
---内部异常堆栈跟踪结束---
---&GT; (内部异常#0)System.Exception:抛出了类型'System.Exception'的异常。
在RxDisposeTests.Program。&lt;&gt; c_ DisplayClass9.b _0()在C:\ Users \ Richard.Hein \ Documents \ Visual Studio 2010 \ Projects \ RxConsole \ RxDisposeTests \ Program.cs:line 25
在System.Threading.Tasks.Task.InnerInvoke()
在System.Threading.Tasks.Task.Execute()&lt; ---
修改强>
不确定TakeUntil是否是一个好的解决方案,因为Task可能会返回除Exceptions之外的其他内容,对吧?所以这可行:
var events = Observable.CreateWithDisposable<IEvent<EventArgs>>(observer =>
{
var eventObs = Observable.FromEvent<EventArgs>(
h => myClass.MyEvent += h, h => myClass.MyEvent -= h);
task.ToObservable().Subscribe(_ => { }, observer.OnError, observer.OnCompleted);
return eventObs.Subscribe(observer.OnNext, observer.OnError, observer.OnCompleted);
});
events.Subscribe(
ev => DoSomethingOnNext(ev),
ex => DoSomethingOnError(ex),
() => DoSomethingOnCompleted());