使用TPL进行任务组合和错误处理

时间:2012-03-06 16:21:34

标签: c# .net task-parallel-library

我有一个具有以下结构的方法:

public Task InitializeAsync()
{
    var taskCompletionSource = new TaskCompletionSource<bool>();

    Task firstTask = ...;

    // secondTask calls taskCompletionSource.TrySetResult(true) once it considers itself "done"
    Task secondTask = firstTask.ContinueWith(..., TaskContinuationOptions.OnlyOnRanToCompletion);

    Action<TasK> errorContinuation = x =>
        {
            taskCompletionSource.SetException(e.Exception);
        };

    firstTask.ContinueWith(errorContinuation, TaskContinuationOptions.OnlyOnFaulted);
    secondTask.ContinueWith(errorContinuation, TaskContinuationOptions.OnlyOnFaulted);

    return taskCompletionSource.Task;
}

重要的:

  • InitializeAsync返回的任务在第二个任务决定
  • 之前不被视为完成
  • secondTask仅在firstTask成功
  • 时运行
  • firstTasksecondTask失败导致整体任务失败

我想知道的是,在实现相同功能的同时,是否有更简洁的方式来表达这一点。我正在使用.NET 4.0,但我对4.5是否也使这更容易感兴趣。

2 个答案:

答案 0 :(得分:5)

对于.NET 4.0,我使用this blog article中的一个想法来链接您描述的任务。请特别注意标题为然后的部分。并不是说他的版本希望你传入一个返回任务的函数,而不是像ContinueWith那样只传递一个方法

顺便说一下,Then让你非常接近你需要能够通过LINQ从子句链接任务所需的SelectMany。我提到这主要是作为语法选项,直到.NET 4.5中的async / await,虽然我实际上并没有自己使用它。

答案 1 :(得分:0)

另一种选择是将两个任务创建为附加子任务(嵌套在您返回的父任务中)

在附加的子任务完成之前,父任务将无法完成。子错误被视为父错误。

http://msdn.microsoft.com/en-us/library/dd997417.aspx