TPL 和异常处理
本文关键字:异常处理 TPL | 更新日期: 2023-09-27 18:29:04
所有,关于上述主题有很多问题,但我相信这已经足够不同,值得提出一个新问题。我有以下Task
和处理各种任务Status
的延续; TaskStatus.RanToCompletion
,TaskStatus.Canceled
,当然还有通过TaskStatus.Faulted
AggregateException
。代码看起来像
Task<bool> asyncTask = Task.Factory.StartNew<bool>(() =>
asyncMethod(uiScheduler, token, someBoolean), token);
asyncTask.ContinueWith(task =>
{
// Check task status.
switch (task.Status)
{
// Handle any exceptions to prevent UnobservedTaskException.
case TaskStatus.RanToCompletion:
if (asyncTask.Result)
{
// Do stuff...
}
break;
case TaskStatus.Faulted:
if (task.Exception != null)
mainForm.progressRightLabelText = task.Exception.InnerException.Message;
else
mainForm.progressRightLabelText = "Operation failed!";
default:
break;
}
}
这一切都很顺利,但我担心我是否做得对,因为有可能从延续中抛出AggregateException
- 然后呢?
我不想Wait
我的asyncTask
或延续,因为这会阻止返回到 UI 线程。捕获从延续中抛出的任何异常并不意味着我必须肯定做这样的事情
Task parentTask = Task.Factory.startNew(() =>
{
Task<bool> asyncTask = Task.Factory.StartNew<bool>(() =>
asyncMethod(uiScheduler, token, someBoolean), token);
Task continueTask = asyncTask.ContinueWith(task =>
{
// My continuation stuff...
}
try
{
continueTask.Wait();
}
catch(AggregateException aggEx)
{
// Some handling here...
}
});
这甚至行得通吗?这里的最佳实践是什么?
一如既往,感谢您的时间。
您可以在委托中使用传统的 try/catch 来监视AggregateException
或者您可以链接特定的延续,这些延续仅在前因使用TaskContinuationOptions.OnlyOnFaulted
选项出错时才运行。后一种方法允许定义非常干净的任务工作流。例如:
Task myRootTask = ....;
myRootTask.ContinueWith(rootAntecdent =>
{
// this will only be executed if the antecedent completed successfully, no need to check for faults
},
TaskContinuationOptions.OnlyOnRanToCompletion);
myRootTask.ContinueWith(rootAntecedent =>
{
// this will only be executed if the antecedent faulted, observe exception and handle accordingly
},
TaskContinuationOptions.OnlyOnFaulted);
Msdn 在这个主题上写得很好"如何":
这里您会注意到他们只是使用 try/catch(AggregateException
( 块,然后过滤他们知道如何在ae.Handle(lambda)
中处理的异常,并在剩下一些无法处理的异常时使应用程序停止。