Task 類別

定義

表示非同步作業。

public ref class Task : IAsyncResult
public ref class Task : IAsyncResult, IDisposable
public class Task : IAsyncResult
public class Task : IAsyncResult, IDisposable
type Task = class
    interface IAsyncResult
type Task = class
    interface IAsyncResult
    interface IDisposable
Public Class Task
Implements IAsyncResult
Public Class Task
Implements IAsyncResult, IDisposable
繼承
Task
衍生
實作

備註

類別 Task 代表不會傳回值且通常以非同步方式執行的單一作業。 Task物件是工作型非同步模式的其中一個中央元件,先在.NET Framework 4 中引進。 由於 物件所 Task 執行的工作通常會以非同步方式線上程集區執行緒上執行,而不是在主要應用程式執行緒上同步執行,因此您可以使用 Status 屬性 IsCanceled 以及 、 IsCompletedIsFaulted 屬性來判斷工作的狀態。 最常使用 Lambda 運算式來指定工作要執行的工作。

針對傳回值的作業,您可以使用 Task<TResult> 類別。

本節內容:

工作具現化範例建立和執行工作分隔工作建立和執行等候一或多個工作完成偵錯工具開發人員的工作和文化特性

工作具現化

下列範例會建立和執行四個工作。 三個 Action<T> 工作會執行名為 action 的委派,其接受 類型的 Object 引數。 第四個工作會在呼叫工作建立方法時內嵌定義委派) 執行 Lambda 運算式 Action (。 每個工作都會以不同的方式具現化並執行:

  • 工作 t1 是藉由呼叫 Task 類別建構函式來具現化,但只有在工作啟動之後 t2 ,才會呼叫其 Start() 方法來啟動。

  • 工作 t2 會藉由呼叫 TaskFactory.StartNew(Action<Object>, Object) 方法,在單一方法呼叫中具現化並啟動。

  • 工作 t3 會藉由呼叫 Run(Action) 方法,在單一方法呼叫中具現化並啟動。

  • 工作 t4 會藉由呼叫 RunSynchronously() 方法,以同步方式在主執行緒上執行。

因為工作 t4 會同步執行,所以會在主要應用程式執行緒上執行。 其餘工作通常會以非同步方式在一或多個執行緒集區執行緒上執行。

using System;
using System.Threading;
using System.Threading.Tasks;

class Example
{
    static void Main()
    {
        Action<object> action = (object obj) =>
                                {
                                   Console.WriteLine("Task={0}, obj={1}, Thread={2}",
                                   Task.CurrentId, obj,
                                   Thread.CurrentThread.ManagedThreadId);
                                };

        // Create a task but do not start it.
        Task t1 = new Task(action, "alpha");

        // Construct a started task
        Task t2 = Task.Factory.StartNew(action, "beta");
        // Block the main thread to demonstrate that t2 is executing
        t2.Wait();

        // Launch t1 
        t1.Start();
        Console.WriteLine("t1 has been launched. (Main Thread={0})",
                          Thread.CurrentThread.ManagedThreadId);
        // Wait for the task to finish.
        t1.Wait();

        // Construct a started task using Task.Run.
        String taskData = "delta";
        Task t3 = Task.Run( () => {Console.WriteLine("Task={0}, obj={1}, Thread={2}",
                                                     Task.CurrentId, taskData,
                                                      Thread.CurrentThread.ManagedThreadId);
                                   });
        // Wait for the task to finish.
        t3.Wait();

        // Construct an unstarted task
        Task t4 = new Task(action, "gamma");
        // Run it synchronously
        t4.RunSynchronously();
        // Although the task was run synchronously, it is a good practice
        // to wait for it in the event exceptions were thrown by the task.
        t4.Wait();
    }
}
// The example displays output like the following:
//       Task=1, obj=beta, Thread=3
//       t1 has been launched. (Main Thread=1)
//       Task=2, obj=alpha, Thread=4
//       Task=3, obj=delta, Thread=3
//       Task=4, obj=gamma, Thread=1
open System.Threading
open System.Threading.Tasks

let action =
    fun (obj: obj) -> printfn $"Task={Task.CurrentId}, obj={obj}, Thread={Thread.CurrentThread.ManagedThreadId}"

// Create a task but do not start it.
let t1 = new Task(action, "alpha")

// Construct a started task
let t2 = Task.Factory.StartNew(action, "beta")
// Block the main thread to demonstrate that t2 is executing
t2.Wait()

// Launch t1
t1.Start()
printfn $"t1 has been launched. (Main Thread={Thread.CurrentThread.ManagedThreadId})"
// Wait for the task to finish.
t1.Wait()

// Construct a started task using Task.Run.
let taskData = "delta"

let t3 =
    Task.Run(fun () -> printfn $"Task={Task.CurrentId}, obj={taskData}, Thread={Thread.CurrentThread.ManagedThreadId}")
// Wait for the task to finish.
t3.Wait()

// Construct an unstarted task
let t4 = new Task(action, "gamma")
// Run it synchronously
t4.RunSynchronously()
// Although the task was run synchronously, it is a good practice
// to wait for it in the event exceptions were thrown by the task.
t4.Wait()


// The example displays output like the following:
//       Task=1, obj=beta, Thread=3
//       t1 has been launched. (Main Thread=1)
//       Task=2, obj=alpha, Thread=4
//       Task=3, obj=delta, Thread=3
//       Task=4, obj=gamma, Thread=1
Imports System.Threading
Imports System.Threading.Tasks

Module Example
    Public Sub Main()
        Dim action As Action(Of Object) = 
              Sub(obj As Object)
                 Console.WriteLine("Task={0}, obj={1}, Thread={2}", 
                 Task.CurrentId, obj,
                 Thread.CurrentThread.ManagedThreadId)
              End Sub

        ' Construct an unstarted task
        Dim t1 As New Task(action, "alpha")

        ' Construct a started task
        Dim t2 As Task = Task.Factory.StartNew(action, "beta")
        ' Block the main thread to demonstrate that t2 is executing
        t2.Wait()

        ' Launch t1 
        t1.Start()
        Console.WriteLine("t1 has been launched. (Main Thread={0})",
                          Thread.CurrentThread.ManagedThreadId)
        ' Wait for the task to finish.
        t1.Wait()

        ' Construct a started task using Task.Run.
        Dim taskData As String = "delta"
        Dim t3 As Task = Task.Run(Sub()
                                     Console.WriteLine("Task={0}, obj={1}, Thread={2}",
                                     Task.CurrentId, taskData,
                                     Thread.CurrentThread.ManagedThreadId)
                                  End Sub)
        ' Wait for the task to finish.
        t3.Wait()
        
        ' Construct an unstarted task
        Dim t4 As New Task(action, "gamma")
        ' Run it synchronously
        t4.RunSynchronously()
        ' Although the task was run synchronously, it is a good practice
        ' to wait for it in the event exceptions were thrown by the task.
        t4.Wait()
    End Sub
End Module
' The example displays output like the following:
'       Task=1, obj=beta, Thread=3
'       t1 has been launched. (Main Thread=1)
'       Task=2, obj=alpha, Thread=3
'       Task=3, obj=delta, Thread=3
'       Task=4, obj=gamma, Thread=1

建立和執行工作

Task 實例可以透過各種方式建立。 從 .NET Framework 4.5 開始,最常見的方法是呼叫靜態 Run 方法。 方法 Run 提供簡單的方法來使用預設值啟動工作,而不需要其他參數。 下列範例會 Run(Action) 使用 方法來啟動迴圈的工作,然後顯示迴圈反復專案的數目:

using System;
using System.Threading.Tasks;

public class Example
{
   public static async Task Main()
   {
      await Task.Run( () => {
                                  // Just loop.
                                  int ctr = 0;
                                  for (ctr = 0; ctr <= 1000000; ctr++)
                                  {}
                                  Console.WriteLine("Finished {0} loop iterations",
                                                    ctr);
                               } );
   }
}
// The example displays the following output:
//        Finished 1000001 loop iterations
open System.Threading.Tasks

let main =
    task {
        do!
            Task.Run(fun () ->
                for i = 0 to 1000000 do
                    printfn $"Finished {i} loop iterations")
    }

main.Wait()

// The example displays the following output:
//        Finished 1000001 loop iterations
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      Dim t As Task = Task.Run(Sub()
                                  ' Just loop.
                                  Dim ctr As Integer = 0
                                  For ctr = 0 to 1000000
                                  Next
                                  Console.WriteLine("Finished {0} loop iterations",
                                                    ctr)
                               End Sub)
      t.Wait()
   End Sub
End Module
' The example displays the following output:
'       Finished 1000001 loop iterations

替代方法,以及在 .NET Framework 4 中啟動工作的最常見方法是靜態 TaskFactory.StartNew 方法。 屬性 Task.Factory 會傳 TaskFactory 回 物件。 方法的多 TaskFactory.StartNew 載可讓您指定要傳遞至工作建立選項和工作排程器的參數。 下列範例會 TaskFactory.StartNew 使用 方法來啟動工作。 它的功能相當於上一個範例中的程式碼。

using System;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
      Task t = Task.Factory.StartNew( () => {
                                  // Just loop.
                                  int ctr = 0;
                                  for (ctr = 0; ctr <= 1000000; ctr++)
                                  {}
                                  Console.WriteLine("Finished {0} loop iterations",
                                                    ctr);
                               } );
      t.Wait();
   }
}
// The example displays the following output:
//        Finished 1000001 loop iterations
open System.Threading.Tasks

let t =
    Task.Factory.StartNew(fun () ->
        // Just loop.
        for i = 0 to 1000000 do
            printfn $"Finished {i} loop iterations")

t.Wait()


// The example displays the following output:
//        Finished 1000001 loop iterations
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      Dim t As Task = Task.Factory.StartNew(Sub()
                                  ' Just loop.
                                  Dim ctr As Integer = 0
                                  For ctr = 0 to 1000000
                                  Next
                                  Console.WriteLine("Finished {0} loop iterations",
                                                    ctr)
                               End Sub)
      t.Wait()
   End Sub
End Module
' The example displays the following output:
'       Finished 1000001 loop iterations

如需更完整的範例,請參閱 以工作為基礎的非同步程式設計

分隔工作建立和執行

類別 Task 也提供初始化工作的建構函式,但不會排程執行工作。 基於效能考慮, Task.RunTaskFactory.StartNew 方法是建立和排程計算工作的慣用機制,但對於必須分隔建立和排程的案例,您可以使用建構函式,然後呼叫 Task.Start 方法來排程工作以供稍後執行。

等候一或多個工作完成

由於工作通常會以非同步方式線上程集區執行緒上執行,因此建立並啟動工作的執行緒會在工作具現化後立即繼續執行。 在某些情況下,當呼叫執行緒是主要應用程式執行緒時,應用程式可能會在工作實際開始執行之前終止。 在其他人中,您的應用程式邏輯可能需要只有在一或多個工作完成執行時,呼叫執行緒才會繼續執行。 您可以藉由呼叫 Wait 方法來等候一或多個工作完成,來同步處理呼叫執行緒的執行及其啟動的非同步工作。

若要等候單一工作完成,您可以呼叫其 Task.Wait 方法。 呼叫 方法會 Wait 封鎖呼叫執行緒,直到單一類別實例完成執行為止。

下列範例會呼叫無 Wait() 參數方法,以無條件等候直到工作完成為止。 工作會呼叫 Thread.Sleep 方法以睡眠兩秒來模擬工作。

using System;   
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static Random rand = new Random();

    static void Main()
    {
        // Wait on a single task with no timeout specified.
        Task taskA = Task.Run( () => Thread.Sleep(2000));
        Console.WriteLine("taskA Status: {0}", taskA.Status);
        try {
          taskA.Wait();
          Console.WriteLine("taskA Status: {0}", taskA.Status);
       } 
       catch (AggregateException) {
          Console.WriteLine("Exception in taskA.");
       }   
    }    
}
// The example displays output like the following:
//     taskA Status: WaitingToRun
//     taskA Status: RanToCompletion
open System
open System.Threading
open System.Threading.Tasks

let rand = Random()

// Wait on a single task with no timeout specified.
let taskA = Task.Run(fun () -> Thread.Sleep 2000)
printfn $"taskA Status: {taskA.Status}"
try 
    taskA.Wait()
    printfn $"taskA Status: {taskA.Status}"

with :? AggregateException ->
    printfn "Exception in taskA."

// The example displays output like the following:
//     taskA Status: WaitingToRun
//     taskA Status: RanToCompletion
Imports System.Threading
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      ' Wait on a single task with no timeout specified.
      Dim taskA = Task.Run( Sub() Thread.Sleep(2000))
      Console.WriteLine("taskA Status: {0}", taskA.Status)
      Try
        taskA.Wait()
        Console.WriteLine("taskA Status: {0}", taskA.Status)
      Catch e As AggregateException
         Console.WriteLine("Exception in taskA.")
      End Try
   End Sub
End Module
' The example displays output like the following:
'     taskA Status: WaitingToRun
'     taskA Status: RanToCompletion

您也可以有條件地等候工作完成。 Wait(Int32)Wait(TimeSpan) 方法會封鎖呼叫執行緒,直到工作完成或逾時間隔經過為止,無論何時先發生。 由於下列範例會啟動睡眠兩秒但定義一秒逾時值的工作,呼叫執行緒會封鎖直到逾時到期,以及工作完成執行之前。

using System;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
      // Wait on a single task with a timeout specified.
      Task taskA = Task.Run( () => Thread.Sleep(2000));
      try {
        taskA.Wait(1000);       // Wait for 1 second.
        bool completed = taskA.IsCompleted;
        Console.WriteLine("Task A completed: {0}, Status: {1}",
                         completed, taskA.Status);
        if (! completed)
           Console.WriteLine("Timed out before task A completed.");                 
       }
       catch (AggregateException) {
          Console.WriteLine("Exception in taskA.");
       }   
   }
}
// The example displays output like the following:
//     Task A completed: False, Status: Running
//     Timed out before task A completed.
open System
open System.Threading
open System.Threading.Tasks

// Wait on a single task with a timeout specified.
let taskA = Task.Run(fun () -> Thread.Sleep 2000)

try
    taskA.Wait 1000 |> ignore // Wait for 1 second.
    let completed = taskA.IsCompleted
    printfn $"Task A completed: {completed}, Status: {taskA.Status}"

    if not completed then
        printfn "Timed out before task A completed."

with :? AggregateException ->
    printfn "Exception in taskA."


// The example displays output like the following:
//     Task A completed: False, Status: Running
//     Timed out before task A completed.
Imports System.Threading
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      ' Wait on a single task with a timeout specified.
      Dim taskA As Task = Task.Run( Sub() Thread.Sleep(2000))
      Try
         taskA.Wait(1000)        ' Wait for 1 second.
         Dim completed As Boolean = taskA.IsCompleted
         Console.WriteLine("Task.Completed: {0}, Status: {1}",
                           completed, taskA.Status)
         If Not completed Then 
            Console.WriteLine("Timed out before task A completed.")
         End If                     
      Catch e As AggregateException
         Console.WriteLine("Exception in taskA.")
      End Try
   End Sub
End Module
' The example displays the following output:
'     Task A completed: False, Status: Running
'     Timed out before task A completed.

您也可以呼叫 Wait(CancellationToken)Wait(Int32, CancellationToken) 方法來提供取消權杖。 如果權杖的 屬性是在 true 方法執行時 Wait 或變成 true ,則方法會擲回 OperationCanceledExceptionIsCancellationRequested

在某些情況下,您可能會想要等候一系列執行中工作的第一個完成,但不要關心它是什麼工作。 為此,您可以呼叫 方法的其中一個多載 Task.WaitAny 。 下列範例會建立三個工作,其中每一個工作都是由亂數產生器決定的間隔睡眠。 方法 WaitAny(Task[]) 會等候第一個工作完成。 然後,此範例會顯示這三項工作狀態的相關資訊。

using System;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
      var tasks = new Task[3];
      var rnd = new Random();
      for (int ctr = 0; ctr <= 2; ctr++)
         tasks[ctr] = Task.Run( () => Thread.Sleep(rnd.Next(500, 3000)));

      try {
         int index = Task.WaitAny(tasks);
         Console.WriteLine("Task #{0} completed first.\n", tasks[index].Id);
         Console.WriteLine("Status of all tasks:");
         foreach (var t in tasks)
            Console.WriteLine("   Task #{0}: {1}", t.Id, t.Status);
      }
      catch (AggregateException) {
         Console.WriteLine("An exception occurred.");
      }
   }
}
// The example displays output like the following:
//     Task #1 completed first.
//     
//     Status of all tasks:
//        Task #3: Running
//        Task #1: RanToCompletion
//        Task #4: Running
open System
open System.Threading
open System.Threading.Tasks

let rnd = new Random()

let tasks =
    [| for _ = 0 to 2 do
           Task.Run(fun () -> rnd.Next(500, 3000) |> Thread.Sleep) |]

try
    let index = Task.WaitAny tasks
    printfn $"Task #{tasks[index].Id} completed first.\n"
    printfn "Status of all tasks:"

    for t in tasks do
        printfn $"   Task #{t.Id}: {t.Status}"

with :? AggregateException ->
    printfn "An exception occurred."

// The example displays output like the following:
//     Task #1 completed first.
//
//     Status of all tasks:
//        Task #3: Running
//        Task #1: RanToCompletion
//        Task #4: Running
Imports System.Threading
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      Dim tasks(2) As Task
      Dim rnd As New Random()
      For ctr As Integer = 0 To 2
         tasks(ctr) = Task.Run( Sub()  Thread.Sleep(rnd.Next(500, 3000)))
      Next
      
      Try 
         Dim index As Integer= Task.WaitAny(tasks)
         Console.WriteLine("Task #{0} completed first.", tasks(index).Id)
         Console.WriteLine()
         Console.WriteLine("Status of all tasks:")
         For Each t in tasks
            Console.WriteLine("   Task #{0}: {1}", t.Id, t.Status)
         Next   
      Catch e As AggregateException
         Console.WriteLine("An exception occurred.")
      End Try
   End Sub
End Module
' The example displays output like the following:
'     Task #1 completed first.
'     
'     Status of all tasks:
'        Task #3: Running
'        Task #1: RanToCompletion
'        Task #4: Running

您也可以呼叫 WaitAll 方法,等候所有一系列的工作完成。 下列範例會建立 10 個工作、等候全部 10 個工作完成,然後顯示其狀態。

using System;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
      // Wait for all tasks to complete.
      Task[] tasks = new Task[10];
      for (int i = 0; i < 10; i++)
      {
          tasks[i] = Task.Run(() => Thread.Sleep(2000));
      }
      try {
         Task.WaitAll(tasks);
      }
      catch (AggregateException ae) {
         Console.WriteLine("One or more exceptions occurred: ");
         foreach (var ex in ae.Flatten().InnerExceptions)
            Console.WriteLine("   {0}", ex.Message);
      }   

      Console.WriteLine("Status of completed tasks:");
      foreach (var t in tasks)
         Console.WriteLine("   Task #{0}: {1}", t.Id, t.Status);
   }
}
// The example displays the following output:
//     Status of completed tasks:
//        Task #2: RanToCompletion
//        Task #1: RanToCompletion
//        Task #3: RanToCompletion
//        Task #4: RanToCompletion
//        Task #6: RanToCompletion
//        Task #5: RanToCompletion
//        Task #7: RanToCompletion
//        Task #8: RanToCompletion
//        Task #9: RanToCompletion
//        Task #10: RanToCompletion
open System
open System.Threading
open System.Threading.Tasks

// Wait for all tasks to complete.
let tasks =
    [| for _ = 0 to 9 do
           Task.Run(fun () -> Thread.Sleep 2000) |]

try
    Task.WaitAll tasks

with :? AggregateException as ae ->
    printfn "One or more exceptions occurred: "

    for ex in ae.Flatten().InnerExceptions do
        printfn $"   {ex.Message}"

printfn "Status of completed tasks:"

for t in tasks do
    printfn $"   Task #{t.Id}: {t.Status}"

// The example displays the following output:
//     Status of completed tasks:
//        Task #2: RanToCompletion
//        Task #1: RanToCompletion
//        Task #3: RanToCompletion
//        Task #4: RanToCompletion
//        Task #6: RanToCompletion
//        Task #5: RanToCompletion
//        Task #7: RanToCompletion
//        Task #8: RanToCompletion
//        Task #9: RanToCompletion
//        Task #10: RanToCompletion
Imports System.Threading
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      ' Wait for all tasks to complete.
      Dim tasks(9) As Task
      For i As Integer = 0 To 9
          tasks(i) = Task.Run( Sub() Thread.Sleep(2000) )
      Next
      Try 
         Task.WaitAll(tasks)
      Catch ae As AggregateException
         Console.WriteLine("One or more exceptions occurred: ")
         For Each ex In ae.Flatten().InnerExceptions
            Console.WriteLine("   {0}", ex.Message)
         Next
      End Try   

      Console.WriteLine("Status of completed tasks:")
      For Each t in tasks
         Console.WriteLine("   Task #{0}: {1}", t.Id, t.Status)
      Next   
   End Sub
End Module
' The example displays the following output:
'     Status of completed tasks:
'        Task #2: RanToCompletion
'        Task #1: RanToCompletion
'        Task #3: RanToCompletion
'        Task #4: RanToCompletion
'        Task #6: RanToCompletion
'        Task #5: RanToCompletion
'        Task #7: RanToCompletion
'        Task #8: RanToCompletion
'        Task #9: RanToCompletion
'        Task #10: RanToCompletion

請注意,當您等候一或多個工作完成時,在執行中工作中擲回的任何例外狀況都會在呼叫 Wait 方法的執行緒上傳播,如下列範例所示。 它會啟動 12 個工作,其中三個工作正常完成,其中三個會擲回例外狀況。 在其餘六個工作中,會在開始之前取消三個工作,並在執行時取消三個工作。 例外狀況會在方法呼叫中 WaitAll 擲回,並由 區塊處理 /trycatch

using System;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
      // Create a cancellation token and cancel it.
      var source1 = new CancellationTokenSource();
      var token1 = source1.Token;
      source1.Cancel();
      // Create a cancellation token for later cancellation.
      var source2 = new CancellationTokenSource();
      var token2 = source2.Token;
       
      // Create a series of tasks that will complete, be cancelled, 
      // timeout, or throw an exception.
      Task[] tasks = new Task[12];
      for (int i = 0; i < 12; i++)
      {
          switch (i % 4) 
          {
             // Task should run to completion.
             case 0:
                tasks[i] = Task.Run(() => Thread.Sleep(2000));
                break;
             // Task should be set to canceled state.
             case 1:   
                tasks[i] = Task.Run( () => Thread.Sleep(2000),
                         token1);
                break;         
             case 2:
                // Task should throw an exception.
                tasks[i] = Task.Run( () => { throw new NotSupportedException(); } );
                break;
             case 3:
                // Task should examine cancellation token.
                tasks[i] = Task.Run( () => { Thread.Sleep(2000); 
                                             if (token2.IsCancellationRequested)
                                                token2.ThrowIfCancellationRequested();
                                             Thread.Sleep(500); }, token2);   
                break;
          }
      }
      Thread.Sleep(250);
      source2.Cancel();
       
      try {
         Task.WaitAll(tasks);
      }
      catch (AggregateException ae) {
          Console.WriteLine("One or more exceptions occurred:");
          foreach (var ex in ae.InnerExceptions)
             Console.WriteLine("   {0}: {1}", ex.GetType().Name, ex.Message);
       }   

      Console.WriteLine("\nStatus of tasks:");
      foreach (var t in tasks) {
         Console.WriteLine("   Task #{0}: {1}", t.Id, t.Status);
         if (t.Exception != null) {
            foreach (var ex in t.Exception.InnerExceptions)
               Console.WriteLine("      {0}: {1}", ex.GetType().Name,
                                 ex.Message);
         }
      }
   }
}
// The example displays output like the following:
//   One or more exceptions occurred:
//      TaskCanceledException: A task was canceled.
//      NotSupportedException: Specified method is not supported.
//      TaskCanceledException: A task was canceled.
//      TaskCanceledException: A task was canceled.
//      NotSupportedException: Specified method is not supported.
//      TaskCanceledException: A task was canceled.
//      TaskCanceledException: A task was canceled.
//      NotSupportedException: Specified method is not supported.
//      TaskCanceledException: A task was canceled.
//   
//   Status of tasks:
//      Task #13: RanToCompletion
//      Task #1: Canceled
//      Task #3: Faulted
//         NotSupportedException: Specified method is not supported.
//      Task #8: Canceled
//      Task #14: RanToCompletion
//      Task #4: Canceled
//      Task #6: Faulted
//         NotSupportedException: Specified method is not supported.
//      Task #7: Canceled
//      Task #15: RanToCompletion
//      Task #9: Canceled
//      Task #11: Faulted
//         NotSupportedException: Specified method is not supported.
//      Task #12: Canceled
open System
open System.Threading
open System.Threading.Tasks

// Create a cancellation token and cancel it.
let source1 = new CancellationTokenSource()
let token1 = source1.Token
source1.Cancel()
// Create a cancellation token for later cancellation.
let source2 = new CancellationTokenSource()
let token2 = source2.Token

// Create a series of tasks that will complete, be cancelled,
// timeout, or throw an exception.
let tasks =
    [| for i in 0..11 do
           match i % 4 with
           // Task should run to completion.
           | 0 -> Task.Run(fun () -> Thread.Sleep 2000)
           // Task should be set to canceled state.
           | 1 -> Task.Run(fun () -> Thread.Sleep 2000, token1)
           // Task should throw an exception.
           | 2 -> Task.Run(fun () -> NotSupportedException())
           // Task should examine cancellation token.
           | _ ->
               Task.Run(fun () ->
                   Thread.Sleep 2000

                   if token2.IsCancellationRequested then
                       token2.ThrowIfCancellationRequested()

                   Thread.Sleep 500, token2) |]


Thread.Sleep 250
source2.Cancel()

try
    Task.WaitAll tasks

with :? AggregateException as ae ->
    printfn "One or more exceptions occurred:"

    for ex in ae.InnerExceptions do
        printfn $"   {ex.GetType().Name}: {ex.Message}"

printfn "\nStatus of tasks:"

for t in tasks do
    printfn $"   Task #{t.Id}: {t.Status}"

    if isNull t.Exception |> not then
        for ex in t.Exception.InnerExceptions do
            printfn $"      {ex.GetType().Name}: {ex.Message}"

// The example displays output like the following:
//   One or more exceptions occurred:
//      TaskCanceledException: A task was canceled.
//      NotSupportedException: Specified method is not supported.
//      TaskCanceledException: A task was canceled.
//      TaskCanceledException: A task was canceled.
//      NotSupportedException: Specified method is not supported.
//      TaskCanceledException: A task was canceled.
//      TaskCanceledException: A task was canceled.
//      NotSupportedException: Specified method is not supported.
//      TaskCanceledException: A task was canceled.
//
//   Status of tasks:
//      Task #13: RanToCompletion
//      Task #1: Canceled
//      Task #3: Faulted
//         NotSupportedException: Specified method is not supported.
//      Task #8: Canceled
//      Task #14: RanToCompletion
//      Task #4: Canceled
//      Task #6: Faulted
//         NotSupportedException: Specified method is not supported.
//      Task #7: Canceled
//      Task #15: RanToCompletion
//      Task #9: Canceled
//      Task #11: Faulted
//         NotSupportedException: Specified method is not supported.
//      Task #12: Canceled
Imports System.Threading
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
      ' Create a cancellation token and cancel it.
      Dim source1 As New CancellationTokenSource()
      Dim token1 As CancellationToken = source1.Token
      source1.Cancel()
      ' Create a cancellation token for later cancellation.
      Dim source2 As New CancellationTokenSource()
      Dim token2 As CancellationToken = source2.Token
       
      ' Create a series of tasks that will complete, be cancelled, 
      ' timeout, or throw an exception.
      Dim tasks(11) As Task
      For i As Integer = 0 To 11
          Select Case i Mod 4 
             ' Task should run to completion.
             Case 0
                tasks(i) = Task.Run( Sub() Thread.Sleep(2000))
             ' Task should be set to canceled state.
             Case 1   
                tasks(i) = Task.Run( Sub() Thread.Sleep(2000), token1)
             Case 2
                ' Task should throw an exception.
                tasks(i) = Task.Run( Sub() 
                                        Throw New NotSupportedException() 
                                     End Sub)
             Case 3
                ' Task should examine cancellation token.
                tasks(i) = Task.Run( Sub() 
                                        Thread.Sleep(2000) 
                                        If token2.IsCancellationRequested
                                           token2.ThrowIfCancellationRequested()
                                        End If
                                        Thread.Sleep(500) 
                                     End Sub, token2)   
          End Select
      Next
      Thread.Sleep(250)
      source2.Cancel()
       
      Try 
         Task.WaitAll(tasks)
      Catch ae As AggregateException
         Console.WriteLine("One or more exceptions occurred:")
         For Each ex in ae.InnerExceptions
             Console.WriteLine("   {0}: {1}", ex.GetType().Name, ex.Message)
         Next
      End Try   
      Console.WriteLine()
      
      Console.WriteLine("Status of tasks:")
      For Each t in tasks
         Console.WriteLine("   Task #{0}: {1}", t.Id, t.Status)
         If t.Exception IsNot Nothing Then
            For Each ex in t.Exception.InnerExceptions
               Console.WriteLine("      {0}: {1}", ex.GetType().Name,
                                 ex.Message)
            Next
         End If
      Next
   End Sub
End Module
' The example displays output like the following:
'   One or more exceptions occurred:
'      TaskCanceledException: A task was canceled.
'      NotSupportedException: Specified method is not supported.
'      TaskCanceledException: A task was canceled.
'      TaskCanceledException: A task was canceled.
'      NotSupportedException: Specified method is not supported.
'      TaskCanceledException: A task was canceled.
'      TaskCanceledException: A task was canceled.
'      NotSupportedException: Specified method is not supported.
'      TaskCanceledException: A task was canceled.
'   
'   Status of tasks:
'      Task #13: RanToCompletion
'      Task #1: Canceled
'      Task #3: Faulted
'         NotSupportedException: Specified method is not supported.
'      Task #8: Canceled
'      Task #14: RanToCompletion
'      Task #4: Canceled
'      Task #6: Faulted
'         NotSupportedException: Specified method is not supported.
'      Task #7: Canceled
'      Task #15: RanToCompletion
'      Task #9: Canceled
'      Task #11: Faulted
'         NotSupportedException: Specified method is not supported.
'      Task #12: Canceled

如需工作型非同步作業中例外狀況處理的詳細資訊,請參閱 例外狀況處理

工作和文化特性

從以 .NET Framework 4.6 為目標的桌面應用程式開始,建立和叫用工作的執行緒文化特性會成為執行緒內容的一部分。 也就是說,不論工作執行所在的執行緒目前文化特性為何,工作目前的文化特性都是呼叫執行緒的文化特性。 對於以 .NET Framework 4.6 之前.NET Framework版本為目標的應用程式,工作的文化特性是工作執行所線上程的文化特性。 如需詳細資訊,請參閱主題中的 CultureInfo 一節。

注意

市集應用程式會遵循設定中的Windows 執行階段,並取得預設文化特性。

針對偵錯工具開發人員

對於實作自訂偵錯工具的開發人員,工作的數個內部和私人成員可能會很有用, (這些成員可能會從發行變更為發行) 。 欄位 m_taskId 會做為屬性的備份存放區 Id ,不過直接從偵錯工具存取此欄位可能會比透過屬性的 getter 方法存取相同的值更有效率, (s_taskIdCounter 計數器用來擷取工作) 的下一個可用識別碼。 同樣地, m_stateFlags 欄位也會儲存工作目前生命週期階段的相關資訊,也可以透過 Status 屬性存取訊號。 欄位 m_action 會儲存工作委派的參考,而 m_stateObject 欄位會儲存開發人員傳遞給工作的非同步狀態。 最後,對於剖析堆疊框架的偵錯工具, InternalWait 此方法會在工作進入等候作業時,提供的潛在標記。

建構函式

Task(Action)

使用指定的動作,初始化新的 Task

Task(Action, CancellationToken)

使用指定的動作和 Task,初始化新的 CancellationToken

Task(Action, CancellationToken, TaskCreationOptions)

使用指定的動作和建立選項,初始化新的 Task

Task(Action, TaskCreationOptions)

使用指定的動作和建立選項,初始化新的 Task

Task(Action<Object>, Object)

使用指定的動作和狀態,初始化新的 Task

Task(Action<Object>, Object, CancellationToken)

使用指定的動作、狀態和選項,初始化新的 Task

Task(Action<Object>, Object, CancellationToken, TaskCreationOptions)

使用指定的動作、狀態和選項,初始化新的 Task

Task(Action<Object>, Object, TaskCreationOptions)

使用指定的動作、狀態和選項,初始化新的 Task

屬性

AsyncState

取得建立 Task 時提供的狀態物件,如果未提供則為 null。

CompletedTask

取得已成功完成的工作。

CreationOptions

取得用來建立這個工作的 TaskCreationOptions

CurrentId

傳回目前執行之 Task 的唯一 ID。

Exception

取得導致 AggregateException 不當結束的 Task。 如果 Task 順利完成,或未擲回任何例外狀況,則這會傳回 null

Factory

提供 Factory 方法的存取,這些 Factory 方法用於建立及設定 TaskTask<TResult> 執行個體。

Id

取得這個 Task 執行個體的 ID。

IsCanceled

取得這個 Task 執行個體是否因取消才完成執行。

IsCompleted

取得值,這個值表示工作是否已經完成。

IsCompletedSuccessfully

取得工作是否執行到完成。

IsFaulted

取得 Task 是否因未處理的例外狀況才完成。

Status

取得這個工作的 TaskStatus

方法

ConfigureAwait(Boolean)

設定用來等候這個 Task 的 awaiter。

ConfigureAwait(ConfigureAwaitOptions)

設定用來等候這個 Task 的 awaiter。

ContinueWith(Action<Task,Object>, Object)

建立當目標 Task 完成時,會接收呼叫端提供的狀態資訊並執行的接續。

ContinueWith(Action<Task,Object>, Object, CancellationToken)

建立當目標 Task 完成時,會接收呼叫端提供的狀態資訊和取消語彙基元,並非同步執行的接續。

ContinueWith(Action<Task,Object>, Object, CancellationToken, TaskContinuationOptions, TaskScheduler)

建立當目標 Task 完成時,會接收呼叫端提供的狀態資訊和取消語彙基元,並執行的接續。 接續會根據一組指定的條件執行,並使用指定的排程器。

ContinueWith(Action<Task,Object>, Object, TaskContinuationOptions)

建立當目標 Task 完成時,會接收呼叫端提供的狀態資訊並執行的接續。 接續會根據一組指定的條件執行。

ContinueWith(Action<Task,Object>, Object, TaskScheduler)

建立當目標 Task 完成時,會接收呼叫端提供的狀態資訊並非同步執行的接續。 接續會使用指定的排程器。

ContinueWith(Action<Task>)

建立當目標 Task 完成時非同步執行的接續。

ContinueWith(Action<Task>, CancellationToken)

建立當目標 Task 完成時,會接收取消語彙基元並非同步執行的接續。

ContinueWith(Action<Task>, CancellationToken, TaskContinuationOptions, TaskScheduler)

建立當目標工作完成時,會根據指定之 TaskContinuationOptions 執行的接續。 接續會接收取消語彙基元,並使用指定的排程器。

ContinueWith(Action<Task>, TaskContinuationOptions)

建立當目標工作完成時,會根據指定之 TaskContinuationOptions 執行的接續。

ContinueWith(Action<Task>, TaskScheduler)

建立當目標 Task 完成時非同步執行的接續。 接續會使用指定的排程器。

ContinueWith<TResult>(Func<Task,Object,TResult>, Object)

建立當目標 Task 完成並傳回值時,會接收呼叫端提供的狀態資訊並非同步執行的接續。

ContinueWith<TResult>(Func<Task,Object,TResult>, Object, CancellationToken)

建立當目標 Task 完成並傳回值時非同步執行的接續。 接續會接收呼叫端提供的狀態資訊和取消語彙基元。

ContinueWith<TResult>(Func<Task,Object,TResult>, Object, CancellationToken, TaskContinuationOptions, TaskScheduler)

建立當目標 Task 完成並傳回值時,會根據指定的工作接續選項來執行的接續。 接續會接收呼叫端提供的狀態資訊和取消語彙基元,並使用指定的排程器。

ContinueWith<TResult>(Func<Task,Object,TResult>, Object, TaskContinuationOptions)

建立當目標 Task 完成時,會根據指定的工作接續選項來執行的接續。 接續會接收呼叫端提供的狀態資訊。

ContinueWith<TResult>(Func<Task,Object,TResult>, Object, TaskScheduler)

建立當目標 Task 完成時非同步執行的接續。 接續會接收呼叫端提供的狀態資訊,並使用指定的排程器。

ContinueWith<TResult>(Func<Task,TResult>)

建立當目標 Task<TResult> 完成並傳回值時非同步執行的接續。

ContinueWith<TResult>(Func<Task,TResult>, CancellationToken)

建立當目標 Task 完成並傳回值時非同步執行的接續。 接續會接收取消語彙基元。

ContinueWith<TResult>(Func<Task,TResult>, CancellationToken, TaskContinuationOptions, TaskScheduler)

建立會根據指定之接續選項執行並傳回值的接續。 接續會接收取消語彙基元,並使用指定的排程器。

ContinueWith<TResult>(Func<Task,TResult>, TaskContinuationOptions)

建立會根據指定之接續選項執行並傳回值的接續。

ContinueWith<TResult>(Func<Task,TResult>, TaskScheduler)

建立當目標 Task 完成並傳回值時非同步執行的接續。 接續會使用指定的排程器。

Delay(Int32)

建立在指定的毫秒數之後完成的工作。

Delay(Int32, CancellationToken)

建立在指定的毫秒數之後完成的可取消工作。

Delay(TimeSpan)

建立在指定時間間隔之後完成的工作。

Delay(TimeSpan, CancellationToken)

建立在指定時間間隔之後完成的可取消工作。

Delay(TimeSpan, TimeProvider)

建立在指定時間間隔之後完成的工作。

Delay(TimeSpan, TimeProvider, CancellationToken)

建立在指定時間間隔之後完成的可取消工作。

Dispose()

釋放 Task 類別目前的執行個體所使用的全部資源。

Dispose(Boolean)

處置 Task,並釋放它的所有 Unmanaged 資源。

Equals(Object)

判斷指定的物件是否等於目前的物件。

(繼承來源 Object)
FromCanceled(CancellationToken)

建立以指定的取消語彙基元取消而完成的 Task

FromCanceled<TResult>(CancellationToken)

建立以指定的取消語彙基元取消而完成的 Task<TResult>

FromException(Exception)

建立以指定例外狀況完成的 Task

FromException<TResult>(Exception)

建立以指定例外狀況完成的 Task<TResult>

FromResult<TResult>(TResult)

建立已成功完成具有指定之結果的 Task<TResult>

GetAwaiter()

取得用來等候這個 Task 的 awaiter。

GetHashCode()

做為預設雜湊函式。

(繼承來源 Object)
GetType()

取得目前執行個體的 Type

(繼承來源 Object)
MemberwiseClone()

建立目前 Object 的淺層複製。

(繼承來源 Object)
Run(Action)

將指定在執行緒集區執行工作排入佇列,並傳回代表該工作的 Task 物件。

Run(Action, CancellationToken)

將指定在執行緒集區執行工作排入佇列,並傳回代表該工作的 Task 物件。 取消權杖可用來在工作尚未開始之前取消工作。

Run(Func<Task>)

將指定在執行緒集區執行的工作排入佇列,並傳回 function 所傳回之工作的 Proxy。

Run(Func<Task>, CancellationToken)

將指定在執行緒集區執行的工作排入佇列,並傳回 function 所傳回之工作的 Proxy。 取消權杖可用來在工作尚未開始之前取消工作。

Run<TResult>(Func<Task<TResult>>)

將指定在執行緒集區執行的工作排入佇列,並傳回 function 所傳回之 Task(TResult) 的 Proxy。 取消權杖可用來在工作尚未開始之前取消工作。

Run<TResult>(Func<Task<TResult>>, CancellationToken)

將指定在執行緒集區執行的工作排入佇列,並傳回 function 所傳回之 Task(TResult) 的 Proxy。

Run<TResult>(Func<TResult>)

將指定在執行緒集區執行工作排入佇列,並傳回代表該工作的 Task<TResult> 物件。 取消權杖可用來在工作尚未開始之前取消工作。

Run<TResult>(Func<TResult>, CancellationToken)

將指定在執行緒集區執行工作排入佇列,並傳回代表該工作的 Task(TResult) 物件。

RunSynchronously()

在目前的 Task 上同步執行 TaskScheduler

RunSynchronously(TaskScheduler)

在提供的 Task 上同步執行 TaskScheduler

Start()

啟動 Task,並排定它在目前的 TaskScheduler 執行。

Start(TaskScheduler)

啟動 Task,並排定它在指定的 TaskScheduler 執行。

ToString()

傳回代表目前物件的字串。

(繼承來源 Object)
Wait()

等候 Task 完成執行。

Wait(CancellationToken)

等候 Task 完成執行。 如果在工作完成之前取消語彙基元已取消,則等候會終止。

Wait(Int32)

等待 Task 在指定的毫秒數內完成執行。

Wait(Int32, CancellationToken)

等候 Task 完成執行。 如果在工作完成之前經過逾時間隔或取消語彙基元已取消,則等候會終止。

Wait(TimeSpan)

等待 Task 在指定的時間間隔內完成執行。

Wait(TimeSpan, CancellationToken)

等候 Task 完成執行。

WaitAll(Task[])

等候所有提供的 Task 物件完成執行。

WaitAll(Task[], CancellationToken)

等候所有提供的 Task 物件完成執行。

WaitAll(Task[], Int32)

等待所有提供的 Task 物件在指定的毫秒數內完成執行。

WaitAll(Task[], Int32, CancellationToken)

等待所有提供的 Task 物件在指定的毫秒數內完成執行。

WaitAll(Task[], TimeSpan)

等候所有提供的可取消 Task 物件在指定的時間間隔內完成執行。

WaitAny(Task[])

等候任一提供的 Task 物件完成執行。

WaitAny(Task[], CancellationToken)

等候所有提供的 Task 物件完成執行。

WaitAny(Task[], Int32)

等候所有提供的 Task 物件在指定的毫秒數內完成執行。

WaitAny(Task[], Int32, CancellationToken)

等待所有提供的 Task 物件在指定的毫秒數內完成執行。

WaitAny(Task[], TimeSpan)

等候其中任何一個提供的 Task 物件在指定的時間間隔內完成執行。

WaitAsync(CancellationToken)

取得 , Task 當這個 Task 完成時,或指定的 CancellationToken 已要求取消時,將會完成。

WaitAsync(TimeSpan)

取得 , Task 當這個 Task 完成或指定的逾時到期時,將會完成。

WaitAsync(TimeSpan, CancellationToken)

Task取得當完成 Task 時、指定逾時到期時,或要求指定 CancellationToken 取消時完成的 。

WaitAsync(TimeSpan, TimeProvider)

取得 , Task 當這個 Task 完成或指定的逾時到期時,將會完成。

WaitAsync(TimeSpan, TimeProvider, CancellationToken)

Task取得當完成 Task 時、指定逾時到期時,或要求指定 CancellationToken 取消時完成的 。

WhenAll(IEnumerable<Task>)

建立一個工作,當可列舉集合中的所有 Task 物件完成時,會完成此工作。

WhenAll(Task[])

建立一個工作,當陣列中的所有 Task 物件完成時,會完成此工作。

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

建立一個工作,當可列舉集合中的所有 Task<TResult> 物件完成時,會完成此工作。

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

建立一個工作,當陣列中的所有 Task<TResult> 物件完成時,會完成此工作。

WhenAny(IEnumerable<Task>)

建立當任一提供的工作完成時才會完成的工作。

WhenAny(Task, Task)

建立將在完成任一個所提供工作時完成的工作。

WhenAny(Task[])

建立當任一提供的工作完成時才會完成的工作。

WhenAny<TResult>(IEnumerable<Task<TResult>>)

建立當任一提供的工作完成時才會完成的工作。

WhenAny<TResult>(Task<TResult>, Task<TResult>)

建立將在完成任一個所提供工作時完成的工作。

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

建立當任一提供的工作完成時才會完成的工作。

Yield()

建立會在等候時以非同步方式遞交 (Yield) 給目前內容的 awaitable 工具。

明確介面實作

IAsyncResult.AsyncWaitHandle

取得 WaitHandle,這個項目可用來等候工作完成。

IAsyncResult.CompletedSynchronously

取得作業是否已同步完成的指示。

擴充方法

DispatcherOperationWait(Task)

無限期等候基礎 DispatcherOperation 完成。

DispatcherOperationWait(Task, TimeSpan)

在指定的時間長度中等候,等候基礎 DispatcherOperation 完成。

IsDispatcherOperationTask(Task)

傳回值,表示這個 Task 是否與 DispatcherOperation 關聯。

AsAsyncAction(Task)

傳回代表已開始的動作的 Windows 執行階段非同步動作。

適用於

執行緒安全性

除了 以外的 Dispose() 所有成員 Task 都是安全線程,而且可以從多個執行緒同時使用。

另請參閱