如何使用Task.WaitAll来等待这两个任务

时间:2014-10-16 21:45:29

标签: c# task-parallel-library

我有以下代码调用2个异步方法并等待结果:

private Task FirstTaskAsync() {
...
}
private Task SecondTaskAsync() {
...
}

private async void Caller() {
   await FirstTaskAsync();
   await SecondTaskAsync();
}

问题是它现在执行并顺序等待每个任务。我想将其更改为Task.WaitAll()。这是我的改变:

private async void Caller() {
   var first = FirstTaskAsync();
   var second = SecondTaskAsync();

   Task.WaitAll(first, second);
}

但是当我测试它时,Task.WaitAll()永远不会返回。你能告诉我缺少什么吗?

2 个答案:

答案 0 :(得分:5)

首先,除非你正在做一个事件处理程序(我怀疑你是),否则你永远不应该async void,如果你做async Task它会让你的问题变得更加明显。< / p>

private async Task Caller() {
   await FirstTaskAsync();
   await SecondTaskAsync();
}

//This still will not work...
private async Task Caller() {
   var first = FirstTaskAsync();
   var second = SecondTaskAsync();

   Task.WaitAll(first, second);
}

Task.WaitAll返回void,您永远不会在第二种方法中使用await,因此您正在同步执行代码并阻止SynchronizationContext which will cause you to get deadlocks like you are seeing.

正确的解决方案不是阻止,而是使用Task.WhenAll返回一个Task本身,它允许你删除async关键字并返回结果

private Task Caller() {
   var first = FirstTaskAsync();
   var second = SecondTaskAsync();

   return Task.WhenAll(first, second);
}

但是,如果Caller()确实是一个事件处理程序,您也可以执行async void并等待结果。

private async void Caller() { //This should only be done if this is a event handler.
   var first = FirstTaskAsync();
   var second = SecondTaskAsync();

   await Task.WhenAll(first, second);
}

答案 1 :(得分:0)

这对你有用吗?

private async void Caller() 
{
    Task[] tasks = new Task[2];
    tasks[0] = FirstTaskAsync();
    tasks[1] = SecondTaskAsync();

    await Task.WhenAll(tasks);
}