WaitAll vs WhenAll

时间:2011-05-25 11:01:17

标签: c# asynchronous async-await task-parallel-library

异步CTP中Task.WaitAll()Task.WhenAll()之间有什么区别? 您能提供一些示例代码来说明不同的用例吗?

4 个答案:

答案 0 :(得分:419)

Task.WaitAll阻止当前线程,直到所有内容都完成。

Task.WhenAll返回任务,表示等待所有内容完成的操作。

这意味着从异步方法中,您可以使用:

await Task.WhenAll(tasks);

...这意味着你的方法会在一切都完成之后继续,但你不会把一个线程绑在那里直到那个时候。

答案 1 :(得分:39)

虽然JonSkeet的回答以一种典型的优秀方式解释了差异,但最大的实际区别是异常处理。编辑:同意 - 它没有最大的实际差异,这是一个区别。

当任何任务抛出时,

Task.WaitAll抛出AggregateException,您可以检查所有抛出的异常。 await await Task.WhenAll AggregateException打开await Task.WhenAll(taskArray)和'返回'只有第一个例外。

当下面的程序用19/11/2016 12:18:37 AM: Task 1 started 19/11/2016 12:18:37 AM: Task 3 started 19/11/2016 12:18:37 AM: Task 2 started Caught Exception in Main at 19/11/2016 12:18:40 AM: Task 1 throwing at 19/11/2016 12:18:38 AM Done. 执行时,输出如下。

Task.WaitAll(taskArray)

当使用19/11/2016 12:19:29 AM: Task 1 started 19/11/2016 12:19:29 AM: Task 2 started 19/11/2016 12:19:29 AM: Task 3 started Caught AggregateException in Main at 19/11/2016 12:19:32 AM: Task 1 throwing at 19/11/2016 12:19:30 AM Caught AggregateException in Main at 19/11/2016 12:19:32 AM: Task 2 throwing at 19/11/2016 12:19:31 AM Caught AggregateException in Main at 19/11/2016 12:19:32 AM: Task 3 throwing at 19/11/2016 12:19:32 AM Done. 执行以下程序时,输出如下。

class MyAmazingProgram
{
    public class CustomException : Exception
    {
        public CustomException(String message) : base(message)
        { }
    }

    static void WaitAndThrow(int id, int waitInMs)
    {
        Console.WriteLine($"{DateTime.UtcNow}: Task {id} started");

        Thread.Sleep(waitInMs);
        throw new CustomException($"Task {id} throwing at {DateTime.UtcNow}");
    }

    static void Main(string[] args)
    {
        Task.Run(async () =>
        {
            await MyAmazingMethodAsync();
        }).Wait();

    }

    static async Task MyAmazingMethodAsync()
    {
        try
        {
            Task[] taskArray = { Task.Factory.StartNew(() => WaitAndThrow(1, 1000)),
                                 Task.Factory.StartNew(() => WaitAndThrow(2, 2000)),
                                 Task.Factory.StartNew(() => WaitAndThrow(3, 3000)) };

            Task.WaitAll(taskArray);
            //await Task.WhenAll(taskArray);
            Console.WriteLine("This isn't going to happen");
        }
        catch (AggregateException ex)
        {
            foreach (var inner in ex.InnerExceptions)
            {
                Console.WriteLine($"Caught AggregateException in Main at {DateTime.UtcNow}: " + inner.Message);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Caught Exception in Main at {DateTime.UtcNow}: " + ex.Message);
        }
        Console.WriteLine("Done.");
        Console.ReadLine();
    }
}

该计划:

settings.py

答案 2 :(得分:15)

作为差异的一个例子 - 如果你有一个任务,它会对UI线程做一些事情(例如,一个代表故事板中动画的任务),如果你Task.WaitAll()那么UI线程被阻止了UI永远不会更新。如果您使用await Task.WhenAll(),则不会阻止UI线程,并且将更新UI。

答案 3 :(得分:4)

他们做什么?

  • 内部都做同样的事情。

有什么区别:

  • WaitAll 是一个阻止呼叫
  • WhenAll -不-代码将继续执行

在以下情况下使用它:

  • 等待全部,如果没有结果就无法继续
  • WhenAll 什么时候才被通知,不会被阻止