共用方式為


Task.WhenAll 方法

定義

建立當所有提供的工作都完成時,將會完成的工作。

多載

名稱 Description
WhenAll(IEnumerable<Task>)

建立一個任務,當可枚舉集合中的所有 Task 物件都完成後,任務才會完成。

WhenAll(ReadOnlySpan<Task>)

建立當所有提供的工作都完成時,將會完成的工作。

WhenAll(Task[])

建立一個任務,當陣列中所有 Task 物件完成後,任務就會完成。

WhenAll<TResult>(ReadOnlySpan<Task<TResult>>)

建立當所有提供的工作都完成時,將會完成的工作。

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

建立一個任務,當可枚舉集合中的所有 Task<TResult> 物件都完成後,任務才會完成。

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

建立一個任務,當陣列中所有 Task<TResult> 物件完成後,任務就會完成。

WhenAll(IEnumerable<Task>)

來源:
Task.cs
來源:
Task.cs
來源:
Task.cs
來源:
Task.cs
來源:
Task.cs

建立一個任務,當可枚舉集合中的所有 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>

要等候完成的工作。

傳回

表示所有所提供工作完成的工作。

例外狀況

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
open System
open System.Net.NetworkInformation
open System.Threading
open System.Threading.Tasks

let mutable failed = 0

let urls =
    [ "www.adatum.com"
      "www.cohovineyard.com"
      "www.cohowinery.com"
      "www.northwindtraders.com"
      "www.contoso.com" ]

let tasks =
    urls
    |> List.map (fun url ->
        Task.Run(fun () ->
            let png = new Ping()

            try
                let reply = png.Send url

                if reply.Status <> IPStatus.Success then
                    Interlocked.Increment &failed |> ignore
                    raise (TimeoutException $"Unable to reach {url}.")
            with :? PingException ->
                Interlocked.Increment &failed |> ignore
                reraise ()))

let t = Task.WhenAll tasks

try
    t.Wait()
with _ ->
    ()

if t.Status = TaskStatus.RanToCompletion then
    printfn "All ping attempts succeeded."
elif t.Status = TaskStatus.Faulted then
    printfn $"{failed} ping attempts 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

備註

回傳Task物件的方法的超載WhenAll通常會在你關心一組任務的狀態或一組任務拋出的異常時被呼叫。

注意

呼叫 to WhenAll(IEnumerable<Task>) 方法不會阻擋呼叫執行緒。

若任一任務在錯誤狀態下完成,回傳任務也會在該 Faulted 狀態完成,其例外將包含每個任務未封裝異常集合的彙整。

如果所提供的任務都沒有錯誤,但至少有一個被取消,回傳任務就會在該 Canceled 狀態結束。

如果沒有任務發生故障,也沒有任務被取消,結果的任務會以該 RanToCompletion 狀態結束。

如果所提供的陣列/可枚舉物中沒有任何任務,回傳的任務會在返回呼叫者之前立即轉換到狀態 RanToCompletion

適用於

WhenAll(ReadOnlySpan<Task>)

來源:
Task.cs
來源:
Task.cs

建立當所有提供的工作都完成時,將會完成的工作。

public:
 static System::Threading::Tasks::Task ^ WhenAll(ReadOnlySpan<System::Threading::Tasks::Task ^> tasks);
public static System.Threading.Tasks.Task WhenAll(scoped ReadOnlySpan<System.Threading.Tasks.Task> tasks);
static member WhenAll : ReadOnlySpan<System.Threading.Tasks.Task> -> System.Threading.Tasks.Task
Public Shared Function WhenAll (tasks As ReadOnlySpan(Of Task)) As Task

參數

tasks
ReadOnlySpan<Task>

要等候完成的工作。

傳回

表示所有所提供工作完成的工作。

例外狀況

tasks 列包含任務 null

備註

如果任何提供的工作都以錯誤狀態完成,則傳回的工作也會以Faulted狀態完成,其中其例外狀況會包含每個所提供工作未包裝例外狀況集的匯總。

如果沒有提供的工作發生錯誤,但至少其中一項已取消,則傳回的工作將會以 [已取消] 狀態結束。

如果沒有任何工作發生錯誤且未取消任何工作,則產生的工作將會以 RanToCompletion 狀態結束。

如果提供的範圍不包含任何工作,傳回的工作將會在傳回給呼叫端之前,立即轉換為 RanToCompletion 狀態。

適用於

WhenAll(Task[])

來源:
Task.cs
來源:
Task.cs
來源:
Task.cs
來源:
Task.cs
來源:
Task.cs

建立一個任務,當陣列中所有 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[]

要等候完成的工作。

傳回

表示所有所提供工作完成的工作。

例外狀況

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
open System
open System.Net.NetworkInformation
open System.Threading
open System.Threading.Tasks

let mutable failed = 0

let urls =
    [| "www.adatum.com"
       "www.cohovineyard.com"
       "www.cohowinery.com"
       "www.northwindtraders.com"
       "www.contoso.com" |]

let tasks =
    urls
    |> Array.map (fun url ->
        Task.Run(fun () ->
            let png = new Ping()

            try
                let reply = png.Send url

                if reply.Status <> IPStatus.Success then
                    Interlocked.Increment &failed |> ignore
                    raise (TimeoutException $"Unable to reach {url}.")
            with :? PingException ->
                Interlocked.Increment &failed |> ignore
                reraise ()))

let main =
    task {
        let t = Task.WhenAll tasks

        try
            do! t
        with _ ->
            ()

        if t.Status = TaskStatus.RanToCompletion then
            printfn "All ping attempts succeeded."
        elif t.Status = TaskStatus.Faulted then
            printfn $"{failed} ping attempts failed"
    }

main.Wait()
// 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

備註

回傳Task物件的方法的超載WhenAll通常會在你關心一組任務的狀態或一組任務拋出的異常時被呼叫。

注意

呼叫 to WhenAll(Task[]) 方法不會阻擋呼叫執行緒。

若任一任務在錯誤狀態下完成,回傳任務也會在該 Faulted 狀態完成,其例外將包含每個任務未封裝異常集合的彙整。

如果所提供的任務都沒有錯誤,但至少有一個被取消,回傳任務就會在該 Canceled 狀態結束。

如果沒有任務發生故障,也沒有任務被取消,結果的任務會以該 RanToCompletion 狀態結束。

如果所提供的陣列/可枚舉物中沒有任何任務,回傳的任務會在返回呼叫者之前立即轉換到狀態 RanToCompletion

適用於

WhenAll<TResult>(ReadOnlySpan<Task<TResult>>)

來源:
Task.cs
來源:
Task.cs

建立當所有提供的工作都完成時,將會完成的工作。

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

類型參數

TResult

任務回傳的結果類型。

參數

tasks
ReadOnlySpan<Task<TResult>>

要等候完成的工作。

傳回

Task<TResult[]>

表示所有所提供工作完成的工作。

例外狀況

tasks 列包含任務 null

備註

如果任何提供的工作都以錯誤狀態完成,則傳回的工作也會以Faulted狀態完成,其中其例外狀況會包含每個所提供工作未包裝例外狀況集的匯總。

如果沒有提供的工作發生錯誤,但至少其中一項已取消,則傳回的工作將會以 [已取消] 狀態結束。

如果沒有任何工作發生錯誤且未取消任何工作,則產生的工作將會以 RanToCompletion 狀態結束。 傳回工作的結果將會設定為陣列,其中包含所提供工作的所有結果,其順序與提供的順序相同(例如,如果輸入工作陣列包含 t1, t2, t3,輸出工作的 Result 會傳回 TResult[] ,其中 arr[0] == t1。Result, arr[1] == t2。Result 和 arr[2] == t3。Result)。

如果提供的陣列舉不包含任何工作,則傳回的工作會在傳回給呼叫端之前,立即轉換為 RanToCompletion 狀態。 傳回的 TResult[] 將是 0 個元素的陣列。

適用於

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

來源:
Task.cs
來源:
Task.cs
來源:
Task.cs
來源:
Task.cs
來源:
Task.cs

建立一個任務,當可枚舉集合中的所有 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 任務。

範例

下列範例會建立10個工作,每個工作都會具現化隨機數產生器,以在1到1,000之間建立1,000個隨機數,並計算其平均值。 此 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
open System
open System.Threading.Tasks

let tasks =
    [| for i = 1 to 10 do
           let delayInterval = 18 * i

           task {
               let mutable total = 0L
               do! Task.Delay delayInterval
               let rnd = Random()

               for _ = 1 to 1000 do
                   total <- total + (rnd.Next(0, 1000) |> int64)

               return total
           } |]

let continuation = Task.WhenAll tasks

try
    continuation.Wait()

with :? AggregateException ->
    ()

if continuation.Status = TaskStatus.RanToCompletion then
    for result in continuation.Result do
        printfn $"Mean: {float result / 1000.:N2}, n = 1,000"

    let grandTotal = continuation.Result |> Array.sum

    printfn $"\nMean of Means: {float grandTotal / 10000.:N2}, n = 10,000"

// Display information on faulted tasks.
else
    for t in tasks do
        printfn $"Task {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> 介面。

備註

呼叫 to 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.cs
來源:
Task.cs
來源:
Task.cs
來源:
Task.cs
來源:
Task.cs

建立一個任務,當陣列中所有 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 任務。

範例

下列範例會建立10個工作,每個工作都會具現化隨機數產生器,以在1到1,000之間建立1,000個隨機數,並計算其平均值。 在這種情況下,十個獨立任務會儲存在一個 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
open System
open System.Threading.Tasks

let tasks =
    [| for i = 1 to 10 do
           let delayInterval = 18 * i

           task {
               let mutable total = 0L
               do! Task.Delay delayInterval
               let rnd = Random()

               for _ = 1 to 1000 do
                   total <- total + (rnd.Next(0, 1000) |> int64)

               return total
           } |]

let continuation = Task.WhenAll tasks

try
    continuation.Wait()

with :? AggregateException ->
    ()

if continuation.Status = TaskStatus.RanToCompletion then
    for result in continuation.Result do
        printfn $"Mean: {float result / 1000.:N2}, n = 1,000"

    let grandTotal = Array.sum continuation.Result

    printfn $"\nMean of Means: {float grandTotal / 10000.:N2}, n = 10,000"

// Display information on faulted tasks.
else
    for t in tasks do
        printfn $"Task {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

備註

呼叫 to 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 的陣列。

適用於