提问者:小点点

运行多个异步任务并等待它们全部完成


我需要在控制台应用程序中运行多个异步任务,并等待它们全部完成,然后再进行进一步处理。

有很多文章,但我似乎越读越糊涂。我已经阅读并理解了任务库的基本原理,但是我显然在某个地方缺少了一个链接。

我知道有可能将任务链起来,这样它们就在另一个任务完成后开始(我读过的所有文章都是这样的),但我希望所有的任务同时运行,我想知道它们是否都完成了。

对于这样的场景,最简单的实现是什么?


共3个答案

匿名用户

两个答案都没有提到等待的:

var task1 = DoWorkAsync();
var task2 = DoMoreWorkAsync();

await Task.WhenAll(task1, task2);

之间的主要区别在于前者会阻塞(类似于在单个任务上使用),而后者不会并且可以等待,在所有任务完成之前将控制权交还给调用方。

此外,异常处理也有所不同:

:

至少有一个任务实例被取消,或者在至少有一个任务实例的执行过程中引发异常。如果任务被取消,AggregateException将在其InnerExceptions集合中包含OperationCanceledException。

:

如果提供的任何任务在错误状态下完成,则返回的任务也将在错误状态下完成,其中其异常将包含来自每个提供的任务的未包装异常集的聚合。

如果提供的任务中没有一个出错,但至少有一个任务被取消,则返回的任务将以已取消状态结束。

如果没有任何任务出错,也没有任何任务被取消,则生成的任务将以RanToCompletion状态结束。如果提供的Array/Enumerable不包含任务,则返回的任务将在返回给调用方之前立即转换到RanToCompletion状态。

匿名用户

您可以创建许多任务,例如:

List<Task> TaskList = new List<Task>();
foreach(...)
{
   var LastTask = new Task(SomeFunction);
   LastTask.Start();
   TaskList.Add(LastTask);
}

Task.WaitAll(TaskList.ToArray());

匿名用户

我见过的最佳选项是以下扩展方法:

public static Task ForEachAsync<T>(this IEnumerable<T> sequence, Func<T, Task> action) {
    return Task.WhenAll(sequence.Select(action));
}

这样称呼它:

await sequence.ForEachAsync(item => item.SomethingAsync(blah));

或者使用异步lambda:

await sequence.ForEachAsync(async item => {
    var more = await GetMoreAsync(item);
    await more.FrobbleAsync();
});

相关问题