我需要在控制台应用程序中运行多个异步任务,并等待它们全部完成,然后再进行进一步处理。
有很多文章,但我似乎越读越糊涂。我已经阅读并理解了任务库的基本原理,但是我显然在某个地方缺少了一个链接。
我知道有可能将任务链起来,这样它们就在另一个任务完成后开始(我读过的所有文章都是这样的),但我希望所有的任务同时运行,我想知道它们是否都完成了。
对于这样的场景,最简单的实现是什么?
两个答案都没有提到等待的
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();
});