Ist Code, der CancellationTokenSource entlastet, während Aufgaben korrekt storniert werden?

8

Ich sehe diesen Code vor mir und ich bin misstrauisch:

%Vor%

Kann man _cts.Dispose () sofort nach dem Abbrechen aufrufen? Würden die zugrunde liegenden Ressourcen der CancellationTokenSource, die für die abgebrochene Aufgabe benötigt werden, nicht erfolgreich auf das CancellationToken warten, wenn es dies tun wollte?

    
Tim Lovell-Smith 21.04.2015, 18:02
quelle

1 Antwort

7
  

Ist es sicher, _cts.Dispose () direkt nach dem Abbrechen aufzurufen?

Um das zu wissen, müssen wir verstehen, was passiert, wenn wir eine CancellationTokenSource abbrechen.

Wenn Sie eine CancellationTokenSource abbrechen, ruft sie alle Callbacks auf, die über die CancellationToken registriert wurden, die über die Methode CancellationToken.Register() einen Verweis auf ihre übergeordnete Quelle enthält.

Wenn Sie jetzt einen CTS entsorgen, wird versucht, alle verknüpften Callbacks, die registriert wurden, vom Token zu entfernen. Wenn es gerade ausgeführt wird, wird es warten, bis der Delegat abgeschlossen ist.

Das bedeutet, dass, obwohl Sie Ihren CTS entsorgt haben, das Objekt immer noch vom Token referenziert wird. Daher ist es immer noch nicht zum Sammeln geeignet.

Sehen wir uns nun CancellationToken.IsCancellationRequested :

an %Vor%

Dies bedeutet, dass die Überprüfung der Stornierung wahr ist, wenn sie erledigt ist. Dies bedeutet, dass es für Sie sicher ist, auf den Abschluss der Aufgaben nach dem Aufruf von dispose zu warten.

Als Nebenbemerkung, wenn Sie (aus irgendeinem Grund) versuchen, ein Token über die entsorgte CancellationTokenSource zu übergeben, treffen Sie auf ObjectDisposedException .

Bearbeiten:

Zwei Dinge, die ich hinzufügen möchte. Lassen Sie mich zunächst sagen, dass ich diesen Ansatz nicht empfehle. Es sollte für einige Codeausführungspfade funktionieren, aber nicht für alle. CancellationTokenSource sollte normalerweise nur dann entsorgt werden, wenn Sie die Eigenschaft WaitHandle verwenden. Ansonsten ist es in Ordnung, es dem GC zu überlassen, die Reinigung durchzuführen. Aber da dies eine Frage des Geschmacks ist, können Sie wählen, was Sie wollen. Ich würde sicherlich empfehlen, nur zu entsorgen, wenn Sie sicher sind, dass die Aufgabe die Stornierungsanfrage eingehalten hat.

Gemäß der Verwendung von WaitHandle wird es nach dem Entsorgen entsorgt und auf Null gesetzt, sodass nicht erreichbar ist .

    
Yuval Itzchakov 21.04.2015, 20:05
quelle