TPL 和异常处理

本文关键字:异常处理 TPL | 更新日期: 2023-09-27 18:29:04

所有,关于上述主题有很多问题,但我相信这已经足够不同,值得提出一个新问题。我有以下Task和处理各种任务Status的延续; TaskStatus.RanToCompletionTaskStatus.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...
        }
    });

这甚至行得通吗?这里的最佳实践是什么?

一如既往,感谢您的时间。

TPL 和异常处理

您可以在委托中使用传统的 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)中处理的异常,并在剩下一些无法处理的异常时使应用程序停止。