任务异常处理无需等待

时间:2016-07-05 19:07:31

标签: c# exception-handling task

使用“任务”时,我不确定如何在不调用“等待我的任务”时如何处理。以下示例不在异步方法中执行。

以下是一个例子:

<action name="*Integration" method="{1}" class="com.integration.webapp.action.IntegrationAction">
        <result name="success" type="tiles">integrationView</result> 
        <result name="integrationDetailsReportResponse" type="tiles">integrationReportView</result>
</action>

将上面的整个块包装起来并捕获Exception是否正确?

我知道我可以等待下面的任务结果并处理异常,但是我的问题与上面的块有关而没有调用t.Wait。

var t = Task.Run(() =>
{
  // do something as part of the task concurrently
});

所以,我的问题是,当我不等待(或等待)任务时,这是否是处理异常的正确方法?

try
{
  t.Wait();  
}
catch(AggregateException ae)
{
  // handle exception(s)
}

UPDATE1 ,或者我应该这样做?

try
{
  var t = Task.Run(() =>
  {
    // do something as part of the task concurrently
  });
}
catch(Exception ex) //NOTE general Exception
{
  // show exception in message box or log it somewhere
}

2 个答案:

答案 0 :(得分:10)

您提供的代码(编辑后)无法帮助您处理内部任务中发生的错误。它只会捕获主代码块中抛出的异常,例如在调度任务或获取传递给它的参数时。

Async / Await简化异步任务控制流程

如果你正在使用C#5及更高版本(与VS2013捆绑在一起),最简单的方法是使用async/await,这简化了异步任务的控制流程:

public async Task DoSomething()
{
    try
    {
        DoSyncWork();
        await Task.Run(() => AsyncStuff());
    }
    catch (Exception ex)
    {  
        // handle.
    }
}

编译器将自动解构异步任务并将异常返回到普通catch块 - 无论代码的同步或异步部分是否抛出异常。

OnlyOnFaulted继续处理任务异常

如果您不使用C#5,或者不想使用async / await(因为您正在处理并行性,而不仅仅是异步),那么该技术是使用Task.ContinueWith来指定如果出现错误,继续:

var task = Task.Run(() => Whatever())
               .ContinueWith(failedTask => HandleError(failedTask), 
                             TaskContinuationOptions.OnlyOnFaulted);

这将导致在原始任务完成后继续启动,但仅在它引发异常时才会启动。您可以使用它根据结果指定多个延续分支:

var baseTask = Task.Run(() => Whatever());            
baseTask.ContinueWith(failedTask => HandleError(failedTask), 
                             TaskContinuationOptions.OnlyOnFaulted);
baseTask.ContinueWith(successfulTask => HandleResults(successfulTask), 
                             TaskContinuationOptions.OnlyOnRanToCompletion);

答案 1 :(得分:3)

在try / catch块中运行任务将永远不会捕获异常(如果没有等待)。任务从与try / catch逻辑分开的自己的线程开始,因此除非指示等待任务完成,否则程序的调用部分将继续。

如果您希望它记录或处理错误,请将该逻辑构建到任务本身。