Task.WhenAll Метод

Определение

Создает задачу, которая будет выполнена после выполнения всех предоставленных задач.

Перегрузки

WhenAll(IEnumerable<Task>)

Создает задачу, которая будет выполнена, когда все объекты Task в перечисляемой коллекции будут завершены.

WhenAll(Task[])

Создает задачу, которая будет выполнена, когда все Task объекты в массиве будут завершены.

WhenAll<TResult>(IEnumerable<Task<TResult>>)

Создает задачу, которая будет выполнена, когда все объекты Task<TResult> в перечисляемой коллекции будут завершены.

WhenAll<TResult>(Task<TResult>[])

Создает задачу, которая будет выполнена, когда все Task<TResult> объекты в массиве будут завершены.

WhenAll(IEnumerable<Task>)

Создает задачу, которая будет выполнена, когда все объекты Task в перечисляемой коллекции будут завершены.

public:
 static System::Threading::Tasks::Task ^ WhenAll(System::Collections::Generic::IEnumerable<System::Threading::Tasks::Task ^> ^ tasks);
public static System.Threading.Tasks.Task WhenAll (System.Collections.Generic.IEnumerable<System.Threading.Tasks.Task> tasks);
static member WhenAll : seq<System.Threading.Tasks.Task> -> System.Threading.Tasks.Task
Public Shared Function WhenAll (tasks As IEnumerable(Of Task)) As Task

Параметры

tasks
IEnumerable<Task>

Задачи, завершение которых требуется подождать.

Возвращаемое значение

Task

Задача, представляющая завершение всех предоставленных задач.

Исключения

Аргумент tasks имел значение null.

Коллекция tasks содержала задачу null.

Примеры

В следующем примере создается набор задач, которые выполняют связь с URL-адресами в массиве. Задачи хранятся в коллекции, передаваемой List<Task> методу WhenAll(IEnumerable<Task>) . После вызова Wait метода убедитесь, что все потоки завершены, в примере проверяется Task.Status свойство, чтобы определить, были ли сбои каких-либо задач.

using System;
using System.Collections.Generic;
using System.Net.NetworkInformation;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
      int failed = 0;
      var tasks = new List<Task>();
      String[] urls = { "www.adatum.com", "www.cohovineyard.com",
                        "www.cohowinery.com", "www.northwindtraders.com",
                        "www.contoso.com" };
      
      foreach (var value in urls) {
         var url = value;
         tasks.Add(Task.Run( () => { var png = new Ping();
                                     try {
                                        var reply = png.Send(url);
                                        if (! (reply.Status == IPStatus.Success)) {
                                           Interlocked.Increment(ref failed);
                                           throw new TimeoutException("Unable to reach " + url + ".");
                                        }
                                     }
                                     catch (PingException) {
                                        Interlocked.Increment(ref failed);
                                        throw;
                                     }
                                   }));
      }
      Task t = Task.WhenAll(tasks);
      try {
         t.Wait();
      }
      catch {}   

      if (t.Status == TaskStatus.RanToCompletion)
         Console.WriteLine("All ping attempts succeeded.");
      else if (t.Status == TaskStatus.Faulted)
         Console.WriteLine("{0} ping attempts failed", failed);      
   }
}
// The example displays output like the following:
//       5 ping attempts failed
Imports System.Collections.Generic
Imports System.Net.NetworkInformation
Imports System.Threading
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      Dim failed As Integer = 0
      Dim tasks As New List(Of Task)()
      Dim urls() As String = { "www.adatum.com", "www.cohovineyard.com",
                              "www.cohowinery.com", "www.northwindtraders.com",
                              "www.contoso.com" }
      
      For Each value In urls
         Dim url As String = value
         tasks.Add(Task.Run( Sub()
                                Dim png As New Ping()
                                Try
                                   Dim reply = png.Send(url)
                                   If Not reply.Status = IPStatus.Success Then
                                      Interlocked.Increment(failed)
                                      Throw New TimeoutException("Unable to reach " + url + ".")
                                   End If
                                   Catch e As PingException
                                      Interlocked.Increment(failed)
                                      Throw
                                   End Try
                             End Sub))
      Next
      Dim t As Task = Task.WhenAll(tasks)
      Try
         t.Wait()
      Catch
      End Try   

      If t.Status = TaskStatus.RanToCompletion
         Console.WriteLine("All ping attempts succeeded.")
      ElseIf t.Status = TaskStatus.Faulted
         Console.WriteLine("{0} ping attempts failed", failed)      
      End If
   End Sub
End Module
' The example displays output like the following:
'     5 ping attempts failed

Комментарии

Перегрузки WhenAll метода, возвращающего Task объект, обычно вызываются при интересе к состоянию набора задач или в исключениях, создаваемых набором задач.

Примечание

WhenAll(IEnumerable<Task>) Вызов метода не блокирует вызывающий поток.

Если какая-либо из предоставленных задач завершается в состоянии сбоя, возвращаемая задача также будет завершена в Faulted состоянии, где его исключения будут содержать агрегирование набора несмеченных исключений из каждой из указанных задач.

Если ни одна из указанных задач не была отменена, но хотя бы одна из них была отменена, возвращенная задача завершится в Canceled состоянии.

Если ни одна из задач не была неисправна и ни одна из задач не была отменена, результирующая задача завершится в RanToCompletion состоянии.

Если предоставленный массив или перечисление не содержит никаких задач, возвращаемая задача немедленно переходит в RanToCompletion состояние до возвращения вызывающему объекту.

Применяется к

WhenAll(Task[])

Создает задачу, которая будет выполнена, когда все Task объекты в массиве будут завершены.

public:
 static System::Threading::Tasks::Task ^ WhenAll(... cli::array <System::Threading::Tasks::Task ^> ^ tasks);
public static System.Threading.Tasks.Task WhenAll (params System.Threading.Tasks.Task[] tasks);
static member WhenAll : System.Threading.Tasks.Task[] -> System.Threading.Tasks.Task
Public Shared Function WhenAll (ParamArray tasks As Task()) As Task

Параметры

tasks
Task[]

Задачи, завершение которых требуется подождать.

Возвращаемое значение

Task

Задача, представляющая завершение всех предоставленных задач.

Исключения

Аргумент tasks имел значение null.

Массив tasks содержал задачу null.

Примеры

В следующем примере создается набор задач, которые выполняют связь с URL-адресами в массиве. Задачи хранятся в коллекции, которая преобразуется в List<Task> массив и передается в WhenAll(IEnumerable<Task>) метод. После вызова Wait метода убедитесь, что все потоки завершены, в примере проверяется Task.Status свойство, чтобы определить, были ли сбои каких-либо задач.

using System;
using System.Collections.Generic;
using System.Net.NetworkInformation;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
   public static async Task Main()
   {
      int failed = 0;
      var tasks = new List<Task>();
      String[] urls = { "www.adatum.com", "www.cohovineyard.com",
                        "www.cohowinery.com", "www.northwindtraders.com",
                        "www.contoso.com" };
      
      foreach (var value in urls) {
         var url = value;
         tasks.Add(Task.Run( () => { var png = new Ping();
                                     try {
                                        var reply = png.Send(url);
                                        if (! (reply.Status == IPStatus.Success)) {
                                           Interlocked.Increment(ref failed);
                                           throw new TimeoutException("Unable to reach " + url + ".");
                                        }
                                     }
                                     catch (PingException) {
                                        Interlocked.Increment(ref failed);
                                        throw;
                                     }
                                   }));
      }
      Task t = Task.WhenAll(tasks.ToArray());
      try {
         await t;
      }
      catch {}   

      if (t.Status == TaskStatus.RanToCompletion)
         Console.WriteLine("All ping attempts succeeded.");
      else if (t.Status == TaskStatus.Faulted)
         Console.WriteLine("{0} ping attempts failed", failed);      
   }
}
// The example displays output like the following:
//       5 ping attempts failed
Imports System.Collections.Generic
Imports System.Net.NetworkInformation
Imports System.Threading
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      Dim failed As Integer = 0
      Dim tasks As New List(Of Task)()
      Dim urls() As String = { "www.adatum.com", "www.cohovineyard.com",
                              "www.cohowinery.com", "www.northwindtraders.com",
                              "www.contoso.com" }
      
      For Each value In urls
         Dim url As String = value
         tasks.Add(Task.Run( Sub()
                                Dim png As New Ping()
                                Try
                                   Dim reply = png.Send(url)
                                   If Not reply.Status = IPStatus.Success Then
                                      Interlocked.Increment(failed)
                                      Throw New TimeoutException("Unable to reach " + url + ".")
                                   End If
                                   Catch e As PingException
                                      Interlocked.Increment(failed)
                                      Throw
                                   End Try
                             End Sub))
      Next
      Dim t As Task = Task.WhenAll(tasks.ToArray())
      Try
         t.Wait()
      Catch
      End Try   

      If t.Status = TaskStatus.RanToCompletion
         Console.WriteLine("All ping attempts succeeded.")
      ElseIf t.Status = TaskStatus.Faulted
         Console.WriteLine("{0} ping attempts failed", failed)      
      End If
   End Sub
End Module
' The example displays output like the following:
'     5 ping attempts failed

Комментарии

Перегрузки WhenAll метода, возвращающего Task объект, обычно вызываются при интересе к состоянию набора задач или в исключениях, создаваемых набором задач.

Примечание

WhenAll(Task[]) Вызов метода не блокирует вызывающий поток.

Если какая-либо из предоставленных задач завершается в состоянии сбоя, возвращаемая задача также будет завершена в Faulted состоянии, где его исключения будут содержать агрегирование набора несмеченных исключений из каждой из указанных задач.

Если ни одна из указанных задач не была отменена, но хотя бы одна из них была отменена, возвращенная задача завершится в Canceled состоянии.

Если ни одна из задач не была неисправна и ни одна из задач не была отменена, результирующая задача завершится в RanToCompletion состоянии.

Если предоставленный массив или перечисление не содержит никаких задач, возвращаемая задача немедленно переходит в RanToCompletion состояние до возвращения вызывающему объекту.

Применяется к

WhenAll<TResult>(IEnumerable<Task<TResult>>)

Создает задачу, которая будет выполнена, когда все объекты Task<TResult> в перечисляемой коллекции будут завершены.

public:
generic <typename TResult>
 static System::Threading::Tasks::Task<cli::array <TResult> ^> ^ WhenAll(System::Collections::Generic::IEnumerable<System::Threading::Tasks::Task<TResult> ^> ^ tasks);
public static System.Threading.Tasks.Task<TResult[]> WhenAll<TResult> (System.Collections.Generic.IEnumerable<System.Threading.Tasks.Task<TResult>> tasks);
static member WhenAll : seq<System.Threading.Tasks.Task<'Result>> -> System.Threading.Tasks.Task<'Result[]>
Public Shared Function WhenAll(Of TResult) (tasks As IEnumerable(Of Task(Of TResult))) As Task(Of TResult())

Параметры типа

TResult

Тип завершенной задачи.

Параметры

tasks
IEnumerable<Task<TResult>>

Задачи, завершение которых требуется подождать.

Возвращаемое значение

Task<TResult[]>

Задача, представляющая завершение всех предоставленных задач.

Исключения

Аргумент tasks имел значение null.

Коллекция tasksсодержала задачу null.

Примеры

В следующем примере создаются десять задач, каждая из которых создает генератор случайных чисел, который создает 1000 случайных чисел от 1 до 1000 и вычисляет их среднее значение. Этот Delay(Int32) метод используется для задержки создания экземпляров генераторов случайных чисел, чтобы они не создавались с одинаковыми начальными значениями. Затем вызов WhenAll метода возвращает Int64 массив, содержащий среднее значение, вычисленное каждой задачей. Затем они используются для вычисления общего среднего значения.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
      var tasks = new List<Task<long>>();
      for (int ctr = 1; ctr <= 10; ctr++) {
         int delayInterval = 18 * ctr;
         tasks.Add(Task.Run(async () => { long total = 0;
                                          await Task.Delay(delayInterval);
                                          var rnd = new Random();
                                          // Generate 1,000 random numbers.
                                          for (int n = 1; n <= 1000; n++)
                                             total += rnd.Next(0, 1000);
                                          return total; } ));
      }
      var continuation = Task.WhenAll(tasks);
      try {
         continuation.Wait();
      }
      catch (AggregateException)
      { }
   
      if (continuation.Status == TaskStatus.RanToCompletion) {
         long grandTotal = 0;
         foreach (var result in continuation.Result) {
            grandTotal += result;
            Console.WriteLine("Mean: {0:N2}, n = 1,000", result/1000.0);
         }
   
         Console.WriteLine("\nMean of Means: {0:N2}, n = 10,000",
                           grandTotal/10000);
      }
      // Display information on faulted tasks.
      else {
         foreach (var t in tasks) {
            Console.WriteLine("Task {0}: {1}", t.Id, t.Status);
         }
      }
   }
}
// The example displays output like the following:
//       Mean: 506.34, n = 1,000
//       Mean: 504.69, n = 1,000
//       Mean: 489.32, n = 1,000
//       Mean: 505.96, n = 1,000
//       Mean: 515.31, n = 1,000
//       Mean: 499.94, n = 1,000
//       Mean: 496.92, n = 1,000
//       Mean: 508.58, n = 1,000
//       Mean: 494.88, n = 1,000
//       Mean: 493.53, n = 1,000
//
//       Mean of Means: 501.55, n = 10,000
Imports System.Collections.Generic
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      Dim tasks As New List(Of Task(Of Long))()
      For ctr As Integer = 1 To 10
         Dim delayInterval As Integer = 18 * ctr
         tasks.Add(Task.Run(Async Function()
                               Dim total As Long = 0
                               Await Task.Delay(delayInterval)
                               Dim rnd As New Random()
                               ' Generate 1,000 random numbers.
                               For n As Integer = 1 To 1000
                                  total += rnd.Next(0, 1000)
                               Next
                               Return total
                            End Function))
      Next
      Dim continuation = Task.WhenAll(tasks)
      Try
         continuation.Wait()
      Catch ae As AggregateException
      End Try
      
      If continuation.Status = TaskStatus.RanToCompletion Then
         Dim grandTotal As Long = 0
         For Each result in continuation.Result
            grandTotal += result
            Console.WriteLine("Mean: {0:N2}, n = 1,000", result/1000)
         Next
         Console.WriteLine()
         Console.WriteLine("Mean of Means: {0:N2}, n = 10,000",
                           grandTotal/10000)
      ' Display information on faulted tasks.
      Else 
         For Each t In tasks
            Console.WriteLine("Task {0}: {1}", t.Id, t.Status)
         Next
      End If
   End Sub
End Module
' The example displays output like the following:
'       Mean: 506.34, n = 1,000
'       Mean: 504.69, n = 1,000
'       Mean: 489.32, n = 1,000
'       Mean: 505.96, n = 1,000
'       Mean: 515.31, n = 1,000
'       Mean: 499.94, n = 1,000
'       Mean: 496.92, n = 1,000
'       Mean: 508.58, n = 1,000
'       Mean: 494.88, n = 1,000
'       Mean: 493.53, n = 1,000
'
'       Mean of Means: 501.55, n = 10,000

В этом случае десять отдельных задач хранятся в объекте List<T> . Класс List<T> реализует интерфейс списка IEnumerable<T>.

Комментарии

WhenAll<TResult>(IEnumerable<Task<TResult>>) Вызов метода не блокирует вызывающий поток. Однако вызов возвращаемого Result свойства блокирует вызывающий поток.

Если какая-либо из предоставленных задач завершается в состоянии сбоя, возвращаемая задача также будет завершена в Faulted состоянии, где его исключения будут содержать агрегирование набора несмеченных исключений из каждой из указанных задач.

Если ни одна из указанных задач не была отменена, но хотя бы одна из них была отменена, возвращенная задача завершится в Canceled состоянии.

Если ни одна из задач не была неисправна и ни одна из задач не была отменена, результирующая задача завершится в RanToCompletion состоянии. Свойство Task<TResult>.Result возвращаемой задачи будет иметь массив, содержащий все результаты предоставленных задач в том же порядке, в котором они были предоставлены (например, если входной массив задач содержит t1, t2, t3, свойство выходной задачи Task<TResult>.Result вернет TResult[] где arr[0] == t1.Result, arr[1] == t2.Result, and arr[2] == t3.Result).

tasks Если аргумент не содержит задач, возвращаемая RanToCompletion задача немедленно переходит в состояние, прежде чем он будет возвращен вызывающему объекту. Возвращенный TResult[] объект будет массивом из 0 элементов.

Применяется к

WhenAll<TResult>(Task<TResult>[])

Создает задачу, которая будет выполнена, когда все Task<TResult> объекты в массиве будут завершены.

public:
generic <typename TResult>
 static System::Threading::Tasks::Task<cli::array <TResult> ^> ^ WhenAll(... cli::array <System::Threading::Tasks::Task<TResult> ^> ^ tasks);
public static System.Threading.Tasks.Task<TResult[]> WhenAll<TResult> (params System.Threading.Tasks.Task<TResult>[] tasks);
static member WhenAll : System.Threading.Tasks.Task<'Result>[] -> System.Threading.Tasks.Task<'Result[]>
Public Shared Function WhenAll(Of TResult) (ParamArray tasks As Task(Of TResult)()) As Task(Of TResult())

Параметры типа

TResult

Тип завершенной задачи.

Параметры

tasks
Task<TResult>[]

Задачи, завершение которых требуется подождать.

Возвращаемое значение

Task<TResult[]>

Задача, представляющая завершение всех предоставленных задач.

Исключения

Аргумент tasks имел значение null.

Массив tasks, содержащший задачу null.

Примеры

В следующем примере создаются десять задач, каждая из которых создает генератор случайных чисел, который создает 1000 случайных чисел от 1 до 1000 и вычисляет их среднее значение. В этом случае десять отдельных задач хранятся в массиве Task<Int64> . Этот Delay(Int32) метод используется для задержки создания экземпляров генераторов случайных чисел, чтобы они не создавались с одинаковыми начальными значениями. Затем вызов WhenAll метода возвращает Int64 массив, содержащий среднее значение, вычисленное каждой задачей. Затем они используются для вычисления общего среднего значения.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
      var tasks = new Task<long>[10];
      for (int ctr = 1; ctr <= 10; ctr++) {
         int delayInterval = 18 * ctr;
         tasks[ctr - 1] = Task.Run(async () => { long total = 0;
                                                 await Task.Delay(delayInterval);
                                                 var rnd = new Random();
                                                 // Generate 1,000 random numbers.
                                                 for (int n = 1; n <= 1000; n++)
                                                    total += rnd.Next(0, 1000);

                                                 return total; } );
      }
      var continuation = Task.WhenAll(tasks);
      try {
         continuation.Wait();
      }
      catch (AggregateException)
      {}
   
      if (continuation.Status == TaskStatus.RanToCompletion) {
         long grandTotal = 0;
         foreach (var result in continuation.Result) {
            grandTotal += result;
            Console.WriteLine("Mean: {0:N2}, n = 1,000", result/1000.0);
         }
   
         Console.WriteLine("\nMean of Means: {0:N2}, n = 10,000",
                           grandTotal/10000);
      }
      // Display information on faulted tasks.
      else { 
         foreach (var t in tasks)
            Console.WriteLine("Task {0}: {1}", t.Id, t.Status);
      }
   }
}
// The example displays output like the following:
//       Mean: 506.38, n = 1,000
//       Mean: 501.01, n = 1,000
//       Mean: 505.36, n = 1,000
//       Mean: 492.00, n = 1,000
//       Mean: 508.36, n = 1,000
//       Mean: 503.99, n = 1,000
//       Mean: 504.95, n = 1,000
//       Mean: 508.58, n = 1,000
//       Mean: 490.23, n = 1,000
//       Mean: 501.59, n = 1,000
//
//       Mean of Means: 502.00, n = 10,000
Imports System.Collections.Generic
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      Dim tasks(9) As Task(Of Long)
      For ctr As Integer = 1 To 10
         Dim delayInterval As Integer = 18 * ctr
         tasks(ctr - 1) =Task.Run(Async Function()
                                     Dim total As Long = 0
                                     Await Task.Delay(delayInterval)
                                     Dim rnd As New Random()
                                     ' Generate 1,000 random numbers.
                                     For n As Integer = 1 To 1000
                                        total += rnd.Next(0, 1000)
                                     Next
                                     Return total
                                  End Function)
      Next
      Dim continuation = Task.WhenAll(tasks)
      Try
         continuation.Wait()
      Catch ae As AggregateException
      End Try
         
      If continuation.Status = TaskStatus.RanToCompletion Then
         Dim grandTotal As Long = 0
         For Each result in continuation.Result
            grandTotal += result
            Console.WriteLine("Mean: {0:N2}, n = 1,000", result/1000)
         Next
         Console.WriteLine()
         Console.WriteLine("Mean of Means: {0:N2}, n = 10,000",
                           grandTotal/10000)
      ' Display information on faulted tasks.
      Else 
         For Each t In tasks
            Console.WriteLine("Task {0}: {1}", t.Id, t.Status)
         Next
      End If
   End Sub
End Module
' The example displays output like the following:
'       Mean: 506.38, n = 1,000
'       Mean: 501.01, n = 1,000
'       Mean: 505.36, n = 1,000
'       Mean: 492.00, n = 1,000
'       Mean: 508.36, n = 1,000
'       Mean: 503.99, n = 1,000
'       Mean: 504.95, n = 1,000
'       Mean: 508.58, n = 1,000
'       Mean: 490.23, n = 1,000
'       Mean: 501.59, n = 1,000
'
'       Mean of Means: 502.00, n = 10,000

Комментарии

WhenAll<TResult>(Task<TResult>[]) Вызов метода не блокирует вызывающий поток. Однако вызов возвращаемого Result свойства блокирует вызывающий поток.

Если какая-либо из предоставленных задач завершается в состоянии сбоя, возвращаемая задача также будет завершена в Faulted состоянии, где его исключения будут содержать агрегирование набора несмеченных исключений из каждой из указанных задач.

Если ни одна из указанных задач не была отменена, но хотя бы одна из них была отменена, возвращенная задача завершится в Canceled состоянии.

Если ни одна из задач не была неисправна и ни одна из задач не была отменена, результирующая задача завершится в RanToCompletion состоянии. Возвращаемая Result задача будет иметь массив, содержащий все результаты предоставленных задач в том же порядке, в котором они были предоставлены (например, если входной массив задач содержит t1, t2, t3, выходные задачи Result возвращают место TResult[] arr[0] == t1.Result, arr[1] == t2.Result, and arr[2] == t3.Result).

Если предоставленный массив или перечисление не содержит никаких задач, возвращаемая задача немедленно переходит в RanToCompletion состояние до возвращения вызывающему объекту. Возвращенный TResult[] объект будет массивом из 0 элементов.

Применяется к