链接C#任务继续中的任务异常为空

时间:2017-02-17 15:38:13

标签: c# asynchronous task

我有一个C#应用程序,它执行一个返回Task的方法。在这种情况下,如果被调用的方法抛出异常,我正在尝试显示一个包含异常详细信息的消息框。

如果我这样称呼它,我可以在task.Exception中看到异常:

MyClass.MyAsyncMethod(cancellationToken)
       .LogExceptions()
       .ContinueWith(task => {
           MessageBox.Show(task.Exception);
       }, cancellationToken, TaskContinuationOptions.NotOnRanToCompletion, TaskScheduler.Default);

但是,如果我添加OnlyOnRanToCompletion延续,task.Exception续语中的NotOnRanToCompletion将变为空:

MyClass.MyAsyncMethod(cancellationToken)
       .LogExceptions()
       .ContinueWith(task => {
           Log.Info("Executed");
       }, cancellationToken, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default)
       .ContinueWith(task => {
           MessageBox.Show(task.Exception);
       }, cancellationToken, TaskContinuationOptions.NotOnRanToCompletion, TaskScheduler.Default);

OnlyOnranToCompletion延续中的代码未执行,但NotOnRanToCompletion延续中的代码已执行且task.Exception为空。为什么会这样?

注意:我无法使用C# >= 5.0asyncawait功能。我也可以通过一个None延续方法来解决这个问题,该方法检查任务的异常参数并确定是否发生了异常。但是,我对为什么会发生上述行为感兴趣。

这是被调用的方法:

public Task<bool> MyAsyncMethod(CancellationToken cancellationToken)
{
    return Task<bool>.Factory.StartNew(() =>
    {
        ...

        try
        {
            var response = request.GetResponse();
            if (response.StatusCode != HttpStatusCode.OK) 
                throw new Exception("Invalid response status code: " + response.StatusCode);
        }
        catch (Exception ex)
        {
            Logger.Error("Request failed", ex));
            throw;
        }
    }, cancellationToken, TaskCreationOptions.None, TaskScheduler.Default);
}

1 个答案:

答案 0 :(得分:4)

没有例外,因为它是继续的Task没有抛出异常。 Task它的延续(前一次调用ContinueWith)将成功完成。

如果你想同时处理错误和非错误情况,你可能最好只有一个延续并检查它是否在该延续中成功,而不是使用延续选项。或者,您可以将Task存储在您正在进行的实际工作中,并将两个延续作为Task的延续,而不是将一个延续作为另一个的延续。