我有3个任务:

private async Task<Cat> FeedCat() {}
private async Task<House> SellHouse() {}
private async Task<Tesla> BuyCar() {}

它们都需要在我的代码继续之前运行,我也需要每个结果。这些结果之间没有任何共同之处

我如何调用和等待3个任务完成,然后得到结果?


当前回答

var dn = await Task.WhenAll<dynamic>(FeedCat(),SellHouse(),BuyCar());

如果你想访问Cat,你可以这样做:

var ct = (Cat)dn[0];

这是非常简单的做法和非常有用的使用,没有必要去追求一个复杂的解决方案。

其他回答

你可以使用Task。如前所述,WhenAll或Task。WaitAll,这取决于您是否希望线程等待。看看这两个解释的链接。

WaitAll vs WhenAll

如果你正在使用c# 7,你可以使用一个方便的包装方法,像这样…

public static class TaskEx
{
    public static async Task<(T1, T2)> WhenAll<T1, T2>(Task<T1> task1, Task<T2> task2)
    {
        return (await task1, await task2);
    }
}

...当您希望等待多个具有不同返回类型的任务时,可以启用这样的方便语法。当然,您必须对等待的不同数量的任务进行多次重载。

var (someInt, someString) = await TaskEx.WhenAll(GetIntAsync(), GetStringAsync());

但是,如果您打算把这个例子变成现实,请参阅Marc Gravell对ValueTask和已经完成的任务的一些优化的回答。

使用任务。然后等待结果:

var tCat = FeedCat();
var tHouse = SellHouse();
var tCar = BuyCar();
await Task.WhenAll(tCat, tHouse, tCar);
Cat cat = await tCat;
House house = await tHouse;
Tesla car = await tCar; 
//as they have all definitely finished, you could also use Task.Value.

你可以把它们存储在任务中,然后等待它们:

var catTask = FeedCat();
var houseTask = SellHouse();
var carTask = BuyCar();

await Task.WhenAll(catTask, houseTask, carTask);

Cat cat = await catTask;
House house = await houseTask;
Car car = await carTask;

当你使用WhenAll后,你可以用await单独拉出结果:

var catTask = FeedCat();
var houseTask = SellHouse();
var carTask = BuyCar();

await Task.WhenAll(catTask, houseTask, carTask);

var cat = await catTask;
var house = await houseTask;
var car = await carTask;

[注意异步方法总是返回“热”(已经启动的)任务。]

你也可以使用Task。结果(因为此时您知道它们都已成功完成)。但是,我推荐使用await,因为它显然是正确的,而Result在其他场景中可能会导致问题。