一尘不染

为什么我要选择多个“ await Task.WhenAll”而不是多个await?

c#

如果我不在乎任务完成的顺序,而只需要全部完成,我还是应该使用await Task.WhenAll而不是多个await?例如,DoWork2下面是一种首选方法DoWork1(为什么?):

using System;
using System.Threading.Tasks;

namespace ConsoleApp
{
    class Program
    {
        static async Task<string> DoTaskAsync(string name, int timeout)
        {
            var start = DateTime.Now;
            Console.WriteLine("Enter {0}, {1}", name, timeout);
            await Task.Delay(timeout);
            Console.WriteLine("Exit {0}, {1}", name, (DateTime.Now - start).TotalMilliseconds);
            return name;
        }

        static async Task DoWork1()
        {
            var t1 = DoTaskAsync("t1.1", 3000);
            var t2 = DoTaskAsync("t1.2", 2000);
            var t3 = DoTaskAsync("t1.3", 1000);

            await t1; await t2; await t3;

            Console.WriteLine("DoWork1 results: {0}", String.Join(", ", t1.Result, t2.Result, t3.Result));
        }

        static async Task DoWork2()
        {
            var t1 = DoTaskAsync("t2.1", 3000);
            var t2 = DoTaskAsync("t2.2", 2000);
            var t3 = DoTaskAsync("t2.3", 1000);

            await Task.WhenAll(t1, t2, t3);

            Console.WriteLine("DoWork2 results: {0}", String.Join(", ", t1.Result, t2.Result, t3.Result));
        }


        static void Main(string[] args)
        {
            Task.WhenAll(DoWork1(), DoWork2()).Wait();
        }
    }
}

阅读 864

收藏
2020-05-19

共1个答案

一尘不染

是的,请使用,WhenAll因为它可以一次传播所有错误。如果有多个等待,则如果较早的等待之一抛出,则会丢失错误。

另一个重要的区别是, 即使存在故障
(故障或取消的任务),WhenAll也将等待所有任务完成。依次手动等待会导致意外的并发,因为要等待的程序部分实际上会提前进行。 __

我认为这也使阅读代码更加容易,因为所需的语义已直接记录在代码中。

2020-05-19