Dies ist mein Kommentar, der in eine Antwort mit Code umgestaltet wurde. Es enthält ein paar Alternativen für die Verwendung von Task.Wait und das asynchrone Muster, dessen Auswahl davon abhängt, ob Sie die Methode aus dem UI-Thread aufrufen. Das Muster «Task abbrechen» bietet die Möglichkeit, eine Aufgabe zurückzuziehen, die aktiviert wurde oder bereits ausgeführt wird. Dadurch wird sichergestellt, dass die Ausführung nicht beginnt oder abgeschlossen wird. Ein Angebot erhält die volle Unterstützung für dieses Muster, wenn es ein Konstrukt bereitstellt, das die Beschreibung für das Muster erfüllt. Wenn mit der Stornierung Nebenwirkungen verbunden sind (z. B. erzwungener Abschluss anderer Aufgaben, wobei die abgebrochene Aufgabe als abgeschlossen markiert wird), wird das Angebot als teilweise Unterstützung eingestuft. Die meisten der untersuchten Angebote unterstützen dieses Muster in ihren Prozessmodellen. Die meisten unterstützen die erste Variante, wie in Abbildung 25 dargestellt: Staffware tut dies mit dem Rückzugskonstrukt, COSA erlaubt Token, von den Stellen vor Aufgaben zu entfernen, iPlanet stellt die AbortActivity-Methode bereit, FileNet stellt das Konstrukt «Terminate Branch» bereit und SAP Workflow stellt den Prozesssteuerungsschritt für diesen Zweck bereit, obwohl er nur begrenzt genutzt wird. BPEL unterstützt die zweite Variante über Fehlerkompensationshandler, die an Aufgaben angefügt sind, ebenso wie BPMN und XPDL mithilfe von Fehlertyptriggern, die an die Grenze der zu löschenden Aufgabe angefügt sind. UML 2.0-ADs bieten eine ähnliche Funktion, indem sie die Aufgabe, die abgebrochen werden soll, in einem unterbrechbaren Bereich platzieren, der durch ein Signal oder eine andere Aufgabe ausgelöst wird. FLOWer unterstützt das Muster nicht direkt, obwohl Aufgaben übersprungen und neu ausgeführt werden können.
Die allgemeine Interpretation des Abbruchaufgabenmusters wird in Abbildung 25 veranschaulicht. Der Trigger, der Aufgabe B aktiviert hat, wird entfernt, sodass die Aufgabe nicht fortgesetzt werden kann. Abbildung 27: Abbrechen des Aufgabenmusters mit garantierter Beendigung In einer Randnotiz sollten Sie wahrscheinlich einen Verweis auf die von Task.Factory.StartNew(() => StartSearchInternal(s.Token), s.Token) zurückgegebene Aufgabe irgendwo in Ihrer ViewModel-Klasse speichern. Sie möchten höchstwahrscheinlich das Ergebnis und jede Ausnahme, die es ausgelöst haben könnte, beobachten. Vielleicht möchten Sie Lucian Wischiks «Async re-entrancy, and the patterns to deal with it» überprüfen. Um ein + Rating (direkte Unterstützung) oder ein +/- Rating (Teilunterstützung) zu erreichen, sollte das Produkt das entsprechende Bewertungskriterium des Musters erfüllen. Andernfalls wird eine – Bewertung (keine Unterstützung) zugewiesen. Dem Muster sind keine spezifischen Kontextbedingungen zugeordnet. Es ist auch ein gutes API-Muster, um Ihr CancellationToken als letzten Parameter zu behalten, den Ihre Methode akzeptiert. Dies passt sowieso gut zu optionalen Parametern, da sie nach allen erforderlichen Parametern angezeigt werden müssen.
Es gibt auch eine zweite Variante des Musters, bei der die Ausführung der Aufgabe bereits begonnen, aber noch nicht abgeschlossen ist. Dieses Szenario wird in Abbildung 26 dargestellt, in dem eine Aufgabe, die aktiviert wurde oder gerade ausgeführt wird, abgebrochen werden kann. Es ist wichtig, für beide Varianten zu beachten, dass der Abbruch nicht garantiert ist und es möglich ist, dass die Ausführung der Aufgabe bis zum Abschluss fortgesetzt wird. Tatsächlich funktioniert die Kündigungs- vs.-Fortsetzungsentscheidung als verzögerte Auswahl, wobei eine Racebedingung zwischen dem Abbruchereignis und der viel langsameren Aufgabe von Ressourcen, die auf Arbeitszuweisungen reagieren, eingerichtet wird. Für alle praktischen Zwecke ist es viel wahrscheinlicher, dass die Kündigung erfolgt, anstatt die Aufgabe weiterzuführen.