咨询区
- 
	Daniel Minnaar 
我需要在 Console 程序中运行多个异步Task,在进一步处理之前我需要等待它们全部完成,我看了很多相关文章,但越来越糊涂,我知道可以将 task 链起来从而实现一个task的异步串行,但我希望多个task一起运行并在后续的某个点上一次获取所有的结果。.
请问是否有最简单的实现方式。
回答区
- 
	NtFreX 
你可以使用 WhenAll,它返回的是一个可等待的 Task 类,你也可以使用 WaitAll,它没有返回值,但可以实现类似 Thread.Sleep 式的阻塞,直到所有的 tasks 完成,取消或者失败。
下面是一些详细的区别。
发生异常时
- 
	WhenALL 
它会返回一个带失败状态的task,异常信息会包含在这个失败task的 AggregateException 中。
- 
	WaitAll 
会直接抛出 AggregateException 异常。
任务被取消时
- 
	WhenALL 
返回Task的任务状态是 TaskStatus.Canceled。
- 
	WaitAll 
会抛出 AggregateException 异常,内部的异常类型是 OperationCanceledException。
线程阻塞
- 
	WhenALL 
不会阻塞当前线程。
- 
	WaitAll 
会阻塞当前线程。
参考如下代码:
var tasks = new Task[] {
    TaskOperationOne(),
    TaskOperationTwo()
};
Task.WaitAll(tasks);
// or
await Task.WhenAll(tasks);
- 
	Virus 
完全可以使用阻塞版本的 Task.WaitAll 来实现。
List<Task> TaskList = new List<Task>();
foreach(...)
{
   var LastTask = new Task(SomeFunction);
   LastTask.Start();
   TaskList.Add(LastTask);
}
Task.WaitAll(TaskList.ToArray());
当然你也可以用  async + await 再配 WhenAll 来实现完全异步,参考如下代码:
var cats = new List<Cat>();
var dog = new Dog();
var loadDataTasks = new Task[]
{
    Task.Run(async () => cats = await LoadCatsAsync()),
    Task.Run(async () => dog = await LoadDogAsync())
};
try
{
    await Task.WhenAll(loadDataTasks);
}
catch (Exception ex)
{
    // handle exception
}
点评区
这种等待多个 Task 的完成状态,一般都是用 WaitAll 和 WhenAll 两种方式实现,当然在 .NET6 中新增了 Parallel.ForEachAsync 方法来是实现异步并发,有兴趣的朋友可以了解下。
