我已经阅读了很多关于如何在TPL中处理异常的内容,但并不是很理解。
我们来看这个示例代码:
var task1 = new Task(() => { throw new Exception("Throw 1"); });
var task2 = task1.ContinueWith(t => Console.WriteLine("Catch 1:{0}", t.Exception.Message),
TaskContinuationOptions.OnlyOnFaulted);
var task3 = task2.ContinueWith(t => Console.WriteLine("Continuation"));
task1.Start();
try {
task1.Wait();
}
catch (Exception ex) {
Console.WriteLine("Wait Exception: {0}", ex.Message);
}
我期望这个会被打印出来
Catch 1
Continuation
但我获得
Catch 1
Continuation
Wait Exception
这意味着当任务完成并且任务终止程序时,异常仍然被视为未处理。如何在延续中处理异常以便于最终器不会抛出呢?同时我希望任务仍处于故障状态,因此在 try/catch 中包装任务是行不通的。背景是我想要按照这里指定的异步事件模式实现错误处理。完整代码如下:
public IAsyncResult Begin(AsyncCallback callback, object state, Action action) {
var task1 = new Task(action);
var task2 = task1.ContinueWith(t => HandleException(t.Exception),
TaskContinuationOptions.OnlyOnFaulted);
if (callback != null) {
var task3 = task2.ContinueWith(t => callback(t),
TaskScheduler.FromCurrentSynchronizationContext());
var task4 = task3.ContinueWith(t => HandleException(t.Exception),
TaskContinuationOptions.OnlyOnFaulted);
}
task1.Start();
return task;
}
t.Wait()
并忽略异常。但这样做行不通,因为延续可能会在另一个Wait()
抛出异常后执行。 - svick