Bestimmte System.Threading.Tasks.Task
Konstruktoren verwenden a CancellationToken
als Parameter:
CancellationTokenSource source = new CancellationTokenSource();
Task t = new Task (/* method */, source.Token);
Was mich daran verblüfft, ist, dass es innerhalb des Methodenkörpers keine Möglichkeit gibt , tatsächlich an das übergebene Token zu gelangen (z. B. nichts dergleichen Task.CurrentTask.CancellationToken
). Das Token muss über einen anderen Mechanismus bereitgestellt werden, z. B. das Statusobjekt oder in einem Lambda erfasst.
Welchen Zweck erfüllt die Bereitstellung des Stornierungs-Tokens im Konstruktor?
Parallel.For
oderParallel.ForEach
Der Konstruktor verwendet das Token für die interne Abbruchbehandlung. Wenn Ihr Code Zugriff auf das Token haben möchte, sind Sie dafür verantwortlich, es an sich selbst weiterzugeben. Ich würde wärmstens empfehlen, das Buch Parallele Programmierung mit Microsoft .NET bei CodePlex zu lesen .
Beispiel für die Verwendung von CTS aus dem Buch:
quelle
token.ThrowIfCancellationRequested();
? In meinem Test ist das Verhalten das gleiche. Irgendwelche Ideen?when cts.Cancel() is called the Task is going to get canceled and end, no matter what you do
Nein. Wenn die Aufgabe vor dem Start abgebrochen wird, wird sie abgebrochen . Wenn der Hauptteil der Aufgabe niemals ein Token überprüft, wird es vollständig ausgeführt , was zu einem RanToCompletion- Status führt. Wenn der Body einOperationCancelledException
z. B. vonThrowIfCancellationRequested
auslöst, prüft Task, ob das CancellationToken dieser Ausnahme mit dem mit der Task verknüpften identisch ist. Wenn dies der Fall ist, wird die Aufgabe abgebrochen . Wenn nicht, ist es fehlerhaft .Stornierung ist kein einfacher Fall, wie viele vielleicht denken. Einige der Feinheiten werden in diesem Blog-Beitrag auf msdn erklärt:
Beispielsweise:
Stornierung in parallelen Erweiterungen
quelle
Hier ist ein Beispiel, das die beiden Punkte in der Antwort von Max Galkin demonstriert :
Ausgabe:
quelle