Frage

Einige System.Threading.Tasks.Task Konstrukteuren nehmen CancellationToken als Parameter:

CancellationTokenSource source = new CancellationTokenSource();
Task t = new Task (/* method */, source.Token);

Was mich an diesen Schikanen ist, dass es kein Weg von innen der Körper Methode, um tatsächlich an der übergebenen Token zu erhalten (zum Beispiel nichts, wie Task.CurrentTask.CancellationToken). Das Token ist in einer Lambda versehen ist, durch einen anderen Mechanismus, wie beispielsweise das Zustandsobjekt oder erfaßt werden.

So welchem ??Zweck die Löschung im Konstruktor Token dienen nicht bereitstellt?

War es hilfreich?

Lösung

Passing dieses Token in die Task-Konstruktor verbindet sie mit dieser Aufgabe.

Stephen Toub Antwort von MSDN :

Das hat zwei wesentliche Vorteile:

  1. Wenn das Token hat Start Löschung beantragt vor der Aufgabe auszuführen, führen Sie die Aufgabe nicht. Anstatt den Übergang zu Running, wird es sofort zu Canceled übergehen. Dies vermeidet die kostet die Aufgabe ausgeführt wird, wenn es nur beim Laufen abgebrochen werden würde trotzdem.
  2. Wenn der Körper der Aufgabe auch die Aufhebung überwacht Token und wirft einen OperationCanceledException dass Token enthält, (Was ThrowIfCancellationRequested der Fall ist), dann, wenn die Aufgabe sieht, dass OperationCanceledException, überprüft er, ob die Token-Matches des OperationCanceledException ist die Aufgabe Zeichen. Ist dies der Fall, wird diese Ausnahme als Bestätigung gesehen von kooperative Löschung und die Aufgabenübergänge zum Abgebrochen Staat (und nicht der Fehlerzustand).

Andere Tipps

Der Konstruktor verwendet die Token für die Stornierung intern handhaben. Wenn Ihr Code Zugriff auf den Token möchten sind Sie verantwortlich für die es sich selbst übergeben. Ich würde empfehlen, die Parallele Programmierung mit Microsoft .NET Buch auf CodePlex lesen.

Beispiel für die Verwendung von CTS aus dem Buch:

CancellationTokenSource cts = new CancellationTokenSource();
CancellationToken token = cts.Token;

Task myTask = Task.Factory.StartNew(() =>
{
    for (...)
    {
        token.ThrowIfCancellationRequested();

        // Body of for loop.
    }
}, token);

// ... elsewhere ...
cts.Cancel();

Eine Stornierung ist nicht einfach ein Fall, wie viele vielleicht denken. Einige der Feinheit werden in dieser Blog-Post auf Msdn erklärt:

Zum Beispiel:

In bestimmten Situationen, in Parallel Extensions und in anderen Systemen, es notwendig ist, ein blockiertes Verfahren aus Gründen aufzuwecken, die nicht fällig sind explizite Kündigung durch einen Benutzer. Zum Beispiel, wenn ein Thread ist blockiert auf blockingCollection.Take () aufgrund der Sammlung leer ist und ein anderer Thread ruft anschließend blockingCollection.CompleteAdding (), dann sollte der erste Anruf wecken und eine InvalidOperationException wirft eine falsche darstellen Nutzung.

http://blogs.msdn.com /b/pfxteam/archive/2009/06/22/9791840.aspx

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top