adr*_*anm 6 .net c# exception-handling task-parallel-library
我已经阅读了很多关于如何处理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);
}
Run Code Online (Sandbox Code Playgroud)
我希望这打印
Catch 1
Continuation
Run Code Online (Sandbox Code Playgroud)
但我明白了
Catch 1
Continuation
Wait Exception
Run Code Online (Sandbox Code Playgroud)
这意味着当任务完成并且任务终结器最终将拆除应用程序时,异常仍被视为未处理.
如何在延续中处理异常,以便终结器不会抛出?同时我希望任务保持在故障状态,因此将任务包装在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;
}
Run Code Online (Sandbox Code Playgroud)
您等待失败的任务,如果您仔细阅读有关 Task.Wait 的文档,您将看到在这种情况下 wait 将重新抛出异常。
但如果你等待,task3一切都应该按预期进行。
当然,你应该记住这一点:
当您使用 OnlyOnFaulted 选项时,可以保证先行词中的 Exception 属性不为 null。您可以使用该属性来捕获异常并查看哪个异常导致任务发生故障。如果不访问 Exception 属性,异常将无法处理。此外,如果您尝试访问已取消或出现故障的任务的 Result 属性,则会引发新的异常。
(参考这里)
最后还有一个关于如何处理任务抛出的异常的好资料
我希望这有帮助。
| 归档时间: |
|
| 查看次数: |
1930 次 |
| 最近记录: |