我有3个任务:

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

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

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


当前回答

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

WaitAll vs WhenAll

其他回答

只需要分别等待这三个任务,在启动它们之后:

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

var cat = await catTask;
var house = await houseTask;
var 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在其他场景中可能会导致问题。

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

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;

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

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.

await语句不是使代码按顺序运行吗?考虑以下代码

class Program
{
    static Stopwatch _stopwatch = new();

    static async Task Main(string[] args)
    {
        Console.WriteLine($"fire hot");
        _stopwatch.Start();
        var carTask = BuyCar();
        var catTask = FeedCat();
        var houseTask = SellHouse();
        await carTask;
        await catTask;
        await houseTask;
        Console.WriteLine($"{_stopwatch.ElapsedMilliseconds} done!");

        Console.WriteLine($"using await");
        _stopwatch.Restart();
        await BuyCar();
        await FeedCat();
        await SellHouse();            

        Console.WriteLine($"{_stopwatch.ElapsedMilliseconds} done!");
    }

    static async Task BuyCar()
    {
        Console.WriteLine($"{_stopwatch.ElapsedMilliseconds} buy car started");
        await Task.Delay(2000);
        Console.WriteLine($"{_stopwatch.ElapsedMilliseconds} buy car done");
    }

    static async Task FeedCat()
    {
        Console.WriteLine($"{_stopwatch.ElapsedMilliseconds} feed cat started");
        await Task.Delay(1000);
        Console.WriteLine($"{_stopwatch.ElapsedMilliseconds} feed cat done");
    }

    static async Task SellHouse()
    {
        Console.WriteLine($"{_stopwatch.ElapsedMilliseconds} sell house started");
        await Task.Delay(10);
        Console.WriteLine($"{_stopwatch.ElapsedMilliseconds} sell house done");
    }
}

fire hot
0 buy car started
3 feed cat started
4 sell house started
18 sell house done
1004 feed cat done
2013 buy car done
2014 done!
using await
0 buy car started
2012 buy car done
2012 feed cat started
3018 feed cat done
3018 sell house started
3033 sell house done
3034 done!