2

我想确保正确使用 ContinueWhenAll。我有许多将运行异步的调用,然后我只想在其他任务成功完成并且对结果进行一些计算以查看是否应该停止处理并返回禁止的 HTTP 之后才完成最终任务结果。我不确定的是最后一行是否真的会等待所有其他任务完成,或者我是否需要以不同的方式构造它。如果是这样,应该如何构造最后一行,以便只有在我通过 if(getPlatformTask.Result...

// run some tasks and then gather them here
Task.Factory.ContinueWhenAll(new Task[]{ getPlatformTask, getUserTask },
    (tasks) =>
    {
        Task.WaitAll(tasks);

        if (getPlatformTask.Result == null || getUserTask.Result == null)
        {
           return Task<HttpResponseMessage>.Factory.StartNew(() =>
           {
              return new HttpResponseMessage(HttpStatusCode.Forbidden);
           });
        }
    });

// will this line below get called before the inner task above completes?   
return base.SendAsync(request, cancellationToken);       
4

1 回答 1

3

如果你想阻塞当前线程直到所有任务完成,你可以简单地使用Task.WaitAll(),不需要使用延续任务。但请记住,阻塞线程是一个除了消耗资源(如内存)之外什么都不做的线程。阻塞线程通常更容易,但效率较低。

代码可能如下所示:

// run the tasks

Task.WaitAll(getPlatformTask, getUserTask);

// process the results

return base.SendAsync(request, cancellationToken);

不,在您的版本中,最后一行可以(并且很可能会)在所有任务完成之前执行。ContinueWhenAll()不会阻塞,这就是它的全部意义所在。

编辑:我刚刚意识到您的方法返回一个Task. 因此,您实际上不必阻塞线程,而是可以Task在所有工作完成后返回一个已完成的。它可能看起来像这样:

// run the tasks

var result = Task.Factory.ContinueWhenAll(
    new[] { getPlatformTask, getUserTask },
    _ =>
    {
        // process the results

        return base.SendAsync(request, cancellationToken);
    });

return result.Unwrap();

在这里,resultTask<Task<HttpResponseMessage>>,但你只需要Task<HttpResponseMessage>。为此,您可以使用Unwrap()方法

于 2012-03-02T21:49:40.247 回答