AufgabenabbruchTask Cancellation

Die System.Threading.Tasks.Task- und System.Threading.Tasks.Task<TResult>-Klasse unterstützen einen Abbruch durch die Verwendung von Abbruchtoken, die in .NET Framework neu sind.The System.Threading.Tasks.Task and System.Threading.Tasks.Task<TResult> classes support cancellation through the use of cancellation tokens in the .NET Framework. Weitere Informationen finden Sie unter Abbruch in verwalteten Threads.For more information, see Cancellation in Managed Threads. In den Task-Klassen erfordert ein Abbruch eine Zusammenarbeit zwischen dem Benutzerdelegaten, der einen abbrechbaren Vorgang darstellt, und dem Code, der den Abbruch angefordert hat.In the Task classes, cancellation involves cooperation between the user delegate, which represents a cancelable operation and the code that requested the cancellation. Für einen erfolgreichen Abbruch muss der anfordernde Code die CancellationTokenSource.Cancel-Methode aufrufen und der Benutzerdelegat den Vorgang rechtzeitig beenden.A successful cancellation involves the requesting code calling the CancellationTokenSource.Cancel method, and the user delegate terminating the operation in a timely manner. Sie können den Vorgang mithilfe einer dieser Optionen beenden:You can terminate the operation by using one of these options:

  • Durch eine einfache Rückkehr vom Delegaten.By simply returning from the delegate. In vielen Fällen reicht dies aus. Eine auf diese Weise abgebrochene Aufgabeninstanz geht jedoch in den Zustand TaskStatus.RanToCompletion und nicht in den Zustand TaskStatus.Canceled über.In many scenarios this is sufficient; however, a task instance that is canceled in this way transitions to the TaskStatus.RanToCompletion state, not to the TaskStatus.Canceled state.

  • Durch Auslösen einer OperationCanceledException und Übergeben des Tokens, für das ein Abbruch angefordert wurde.By throwing a OperationCanceledException and passing it the token on which cancellation was requested. Die bevorzugte Methode hierfür ist die ThrowIfCancellationRequested -Methode.The preferred way to do this is to use the ThrowIfCancellationRequested method. Eine auf diese Weise abgebrochene Aufgabe geht in den Zustand "Canceled" über, anhand dessen der aufrufende Code überprüfen kann, ob die Aufgabe auf seine Abbruchanforderung reagiert hat.A task that is canceled in this way transitions to the Canceled state, which the calling code can use to verify that the task responded to its cancellation request.

Im folgenden Beispiel wird das grundlegende Muster für den Aufgabenabbruch gezeigt, der die Ausnahme auslöst.The following example shows the basic pattern for task cancellation that throws the exception. Beachten Sie, dass das Token an den Benutzerdelegaten und die Aufgabeninstanz selbst übergeben wird.Note that the token is passed to the user delegate and to the task instance itself.

using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
    static void Main()
    {
        var tokenSource2 = new CancellationTokenSource();
        CancellationToken ct = tokenSource2.Token;

        var task = Task.Factory.StartNew(() =>
        {

            // 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 StartNew.

        tokenSource2.Cancel();

        // Just continue on this thread, or Wait/WaitAll with try-catch:
        try
        {
            task.Wait();
        }
        catch (AggregateException e)
        {
            foreach (var v in e.InnerExceptions)
                Console.WriteLine(e.Message + " " + v.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

Ein umfangreicheres Beispiel finden Sie unter Gewusst wie: Abbrechen einer Aufgabe und ihrer untergeordneten Elemente.For a more complete example, see How to: Cancel a Task and Its Children.

Wenn eine Aufgabeninstanz eine OperationCanceledException beobachtet, die von Benutzercode ausgelöst wurde, vergleicht sie das Token der Ausnahme mit dem zugeordneten Token (das an die API übergeben wurde, die die Aufgabe erstellt hat).When a task instance observes an OperationCanceledException thrown by user code, it compares the exception's token to its associated token (the one that was passed to the API that created the Task). Wenn diese identisch sind und die IsCancellationRequested -Eigenschaft des Tokens true zurückgibt, interpretiert die Aufgabe dies als Bestätigung des Abbruchs und geht in den Zustand Canceled über.If they are the same and the token's IsCancellationRequested property returns true, the task interprets this as acknowledging cancellation and transitions to the Canceled state. Wenn Sie nicht mithilfe einer Wait -Methode oder WaitAll -Methode auf die Aufgabe warten, wird der Status der Aufgabe auf Canceledfestgelegt.If you do not use a Wait or WaitAll method to wait for the task, then the task just sets its status to Canceled.

Wenn Sie auf eine Aufgabe warten, die in den Zustand „Canceled“ übergeht, wird eine System.Threading.Tasks.TaskCanceledException-Ausnahme (eingebunden in eine AggregateException-Ausnahme) ausgelöst.If you are waiting on a Task that transitions to the Canceled state, a System.Threading.Tasks.TaskCanceledException exception (wrapped in an AggregateException exception) is thrown. Beachten Sie, dass diese Ausnahme keinen Fehler, sondern einen erfolgreichen Abbruch kennzeichnet.Note that this exception indicates successful cancellation instead of a faulty situation. Daher gibt die Eigenschaft Exception der Aufgabe nullzurück.Therefore, the task's Exception property returns null.

Wenn die IsCancellationRequested -Eigenschaft des Tokens false zurückgibt oder das Token der Ausnahme nicht mit dem Token der Aufgabe übereinstimmt, wird die OperationCanceledException wie eine normale Ausnahme behandelt, durch die die Aufgabe in den Zustand "Faulted" übergeht.If the token's IsCancellationRequested property returns false or if the exception's token does not match the Task's token, the OperationCanceledException is treated like a normal exception, causing the Task to transition to the Faulted state. Beachten Sie weiterhin, dass die Aufgabe bei weiteren Ausnahmen ebenfalls in den Zustand "Faulted" übergeht.Also note that the presence of other exceptions will also cause the Task to transition to the Faulted state. Sie können den Status der abgeschlossenen Aufgabe in der Status -Eigenschaft abrufen.You can get the status of the completed task in the Status property.

Es ist möglich, dass eine Aufgabe nach dem Anfordern des Abbruchs weiterhin einige Elemente verarbeitet.It is possible that a task may continue to process some items after cancellation is requested.

Siehe auchSee Also

Abbruch in verwalteten ThreadsCancellation in Managed Threads
Gewusst wie: Abbrechen einer Aufgabe und ihrer untergeordneten ElementeHow to: Cancel a Task and Its Children