Benutzer mit den meisten Antworten
TPL - CancellationToken

Frage
-
Hallo zusammen,
ich beschäftige mich zur Zeit mit der TPL und bleibe im wahrsten Sinn des Wortes bei der Verwendung des CancellationTokens bzw. der ThrowIfCancellationRequested-Methode hängen.
Hier die Deklarationen:
Private cts As CancellationTokenSource Private token As CancellationToken Private myTask As task
Der Task:
myTask = Task.Factory.StartNew(Sub() Do 'irgendein Code 'auf Abbruchanforderung reagieren: If token.IsCancellationRequested Then 'Auslösen einer Exception token.ThrowIfCancellationRequested() End If Loop End Sub, token)
Auslösen der Anforderung zum Task-Abbruch:
cts.Cancel 'Den Fehler auffangen und anzeigen Try myTask.Wait() Catch ex As AggregateException For Each v in ex.InnerExceptions 'Code Next End Try
Der Code zum Task-Abbruch befindet sich innerhalb eines Button_Click-Ereignisses. Klicke ich diesen Button an, erhalte ich diese Fehlermeldung bei der Anweisung "token.ThrowIfCancellationRequested()":
Weshalb taucht diese Fehlermeldung auf, wenn das auslösende Element, das "Wait"-Statement sich in einer Try-/Catch-Fehlerbehandlungsroutine befindet? Meinem Verständnis nach müsste die Exception dadurch doch abgefangen werden?
Vielen Dank und viele Grüße
Michael
Antworten
-
Hallo Michael,
in dem Fall liegt es daran, dass der Debugger sich vordrängelt, siehe dazu:
FAQ :: The Debugger does not correctly handle Task exceptions?
Du solltest Dir auch mal anschauen: Parallel Programming: Task Cancellation
Ist zwar C#, sollte aber ohne Probleme auf VB übertragbar sein und zeigt einige Möglichkeiten wie man mit Abbrüchen umgehen kann.
Im übrigen würde ich das CancellationToken nicht als Member Variable speichern, man kann es jederzeit aus der CancellationTokenSource neu erzeugen. Es ist bewusst als leichtgewichtige Struktur angelegt.
Gruß Elmar
- Als Antwort markiert Bayer, Michael Dienstag, 22. Juli 2014 09:21
Alle Antworten
-
Hallo Michael,
in dem Fall liegt es daran, dass der Debugger sich vordrängelt, siehe dazu:
FAQ :: The Debugger does not correctly handle Task exceptions?
Du solltest Dir auch mal anschauen: Parallel Programming: Task Cancellation
Ist zwar C#, sollte aber ohne Probleme auf VB übertragbar sein und zeigt einige Möglichkeiten wie man mit Abbrüchen umgehen kann.
Im übrigen würde ich das CancellationToken nicht als Member Variable speichern, man kann es jederzeit aus der CancellationTokenSource neu erzeugen. Es ist bewusst als leichtgewichtige Struktur angelegt.
Gruß Elmar
- Als Antwort markiert Bayer, Michael Dienstag, 22. Juli 2014 09:21
-
Hallo Elmar,
vielen Dank für die wieder einmal hilfreiche Antwort.
Wenn Du schreibst, Du würdest das CancellationToken nicht als Member Variable speichern, da man es jederzeit aus der CancellationTokenSource erzeugen kann - wie würde der von mir gepostete Code dann aussehen - sprich, wie erzeuge ich das Token aus der Source?
Viele Grüße
Michael
-
Hallo Michael,
das CancelToken ist abhängig von CancellationTokenSource und somit würdest Du zwei Variablen zum gleichen Kontext speichern.
Über CancellationTokenSource kannst Du jederzeit ein Token abrufen, die verweisen alle auf die gleiche Quelle. Für oben zum Beispiel:
myTask = Task.Factory.StartNew( Sub() Dim token = cts.Token ' oder als Methoden Argument Do 'irgendein Code ' Ein Test wäre doppelt gehoppelt, da ThrowIf genau dies tut token.ThrowIfCancellationRequested() Loop End Sub, cts.Token)
Das zusätzliche If kann man sich ebenfalls sparen, denn wie ThrowIf es beschreibt, macht es genau das. Siehe auch: Recommended patterns for CancellationToken
Dort kommt stellenweise Async / Await zum Einsatz, was man ab VB 2012 bevorzugen sollte, da es doch einiges vereinfacht, sobald auf Thread gewartet werden muss, siehe Asynchrone Programmierung mit Async und Await
Gruß Elmar