共用方式為


任務取消

System.Threading.Tasks.TaskSystem.Threading.Tasks.Task<TResult> 類別透過取消標記來支援取消。 如需詳細資訊,請參閱 管理線程中的取消操作。 在 Task 類別中,取消涉及用戶委派與請求取消的程式碼之間的合作,其中用戶委派代表可取消的操作。 成功的取消涉及要求程式碼呼叫CancellationTokenSource.Cancel方法,並且使用者委派會及時終止操作。 您可以使用下列其中一個選項來終止作業:

下列範例顯示引發例外狀況的工作取消基本模式:

備註

令牌會傳遞給使用者委派和工作實例。

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

class Program
{
    static async Task Main()
    {
        var tokenSource2 = new CancellationTokenSource();
        CancellationToken ct = tokenSource2.Token;

        var task = Task.Run(() =>
        {
            // Were we already canceled?
            ct.ThrowIfCancellationRequested();

            bool moreToDo = true;
            while (moreToDo)
            {
                // Poll on this property if you have to do
                // other cleanup before throwing.
                if (ct.IsCancellationRequested)
                {
                    // Clean up here, then...
                    ct.ThrowIfCancellationRequested();
                }
            }
        }, tokenSource2.Token); // Pass same token to Task.Run.

        tokenSource2.Cancel();

        // Just continue on this thread, or await with try-catch:
        try
        {
            await task;
        }
        catch (OperationCanceledException e)
        {
            Console.WriteLine($"{nameof(OperationCanceledException)} thrown with message: {e.Message}");
        }
        finally
        {
            tokenSource2.Dispose();
        }

        Console.ReadKey();
    }
}
Imports System.Threading
Imports System.Threading.Tasks

Module Test
    Sub Main()
        Dim tokenSource2 As New CancellationTokenSource()
        Dim ct As CancellationToken = tokenSource2.Token

        Dim t2 = Task.Factory.StartNew(Sub()
                                           ' Were we already canceled?
                                           ct.ThrowIfCancellationRequested()

                                           Dim moreToDo As Boolean = True
                                           While moreToDo = True
                                               ' Poll on this property if you have to do
                                               ' other cleanup before throwing.
                                               If ct.IsCancellationRequested Then

                                                   ' Clean up here, then...
                                                   ct.ThrowIfCancellationRequested()
                                               End If

                                           End While
                                       End Sub _
        , tokenSource2.Token) ' Pass same token to StartNew.

        ' Cancel the task.
        tokenSource2.Cancel()

        ' Just continue on this thread, or Wait/WaitAll with try-catch:
        Try
            t2.Wait()

        Catch e As AggregateException

            For Each item In e.InnerExceptions
                Console.WriteLine(e.Message & " " & item.Message)
            Next
        Finally
            tokenSource2.Dispose()
        End Try

        Console.ReadKey()
    End Sub
End Module

如需完整的範例,請參閱 如何:取消任務及其子任務

當任務實例觀察到使用者程式碼擲出OperationCanceledException時,它會比較該例外狀況的令牌與其相關聯的令牌(傳遞至 API 以建立任務)。 如果令牌相同且令牌的 IsCancellationRequested 屬性傳回 true,該工作會將此解譯為認可取消,並轉換為已取消狀態。 如果您不使用 WaitWaitAll 方法來等候工作,則工作只會將其狀態設定為 Canceled

如果您正在等候一個轉換至已取消狀態的工作,則會拋出一個例外狀況(此例外狀況被包裝在例外狀況 System.Threading.Tasks.TaskCanceledException 中)。 此例外狀況表示取消成功,而不是發生錯誤的情況。 因此,工作的 Exception 屬性會傳回 null

如果令牌的 IsCancellationRequested 屬性返回 false,或者例外狀況的令牌不符合 Task 的令牌,則 OperationCanceledException 會被視為一般例外狀況,導致 Task 轉換為出錯狀態。 其他例外狀況的存在也會導致工作轉換為錯誤狀態。 您可以在 屬性中 Status 取得已完成工作的狀態。

在要求取消之後,工作可能會繼續處理某些項目。

另請參閱