WaitAll vs WhenAll

В чем разница между Task.WaitAll() и Task.WhenAll() от Async CTP? Можете ли вы предоставить примерный код для иллюстрации различных вариантов использования?

Task.WaitAll блокирует текущий stream, пока все не завершится.

Task.WhenAll возвращает задачу, которая представляет действие ожидания до тех пор, пока все не завершится.

Это означает, что из метода async вы можете использовать:

 await Task.WhenAll(tasks); 

… что означает, что ваш метод будет продолжаться, когда все будет завершено, но вы не будете связывать нить, чтобы просто повесить до этого времени.

Хотя ответ JonSkeet объясняет разницу в отличном для меня способе, самым большим практическим отличием является обработка исключений .

Task.WaitAll выдает Task.WaitAll AggregateException когда бросается какая-либо из задач, и вы можете проверить все заброшенные исключения. await Task.WhenAll в 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(); } } 

В качестве примера разницы – если у вас есть задача, что-то делает с streamом пользовательского интерфейса (например, задача, представляющая анимацию в раскадровке), если вы Task.WaitAll() тогда stream пользовательского интерфейса блокируется и пользовательский интерфейс никогда не обновлено. если вы используете await Task.WhenAll() тогда stream пользовательского интерфейса не блокируется, и пользовательский интерфейс будет обновлен.

Что они делают:

  • Внутренне оба делают то же самое.

Какая разница:

  • WaitAll – это блокирующий вызов
  • Когда All – not – code будет продолжать выполнение

Используйте, когда:

  • WaitAll, когда не может продолжаться без результата
  • WhenAll, когда только что уведомляться, не блокируется
  • Выполнение задачи в фоновом режиме в приложении WPF
  • Должны ли мы переключиться на использование асинхронного ввода-вывода по умолчанию?
  • Запуск задач в foreach Loop использует значение последнего элемента
  • Вызов синхронного асинхронного метода
  • Почему это асинхронное действие зависает?
  • ConfigureAwait подталкивает продолжение в stream пула
  • В чем разница между возвратом пустоты и возвратом задачи?
  • Давайте будем гением компьютера.