Wir haben bereits ein Beispiel für die Stornierung im Abschnitt Nicht blockierende Anrufe gesehen. In diesem Abschnitt werden wir die Stornierung genauer überprüfen. Im obigen Beispiel wird die Stornierung von bgSyncTask Generator.prototype.return verwenden, um den Generator direkt zum finally-Block springen zu lassen. Hier können Sie yield cancelled() verwenden, um zu überprüfen, ob der Generator abgebrochen wurde oder nicht. Sie können Task direkt oder das async await-Muster verwenden, um den Code zu vereinfachen. Für diesen Beitrag werden wir letztere verwenden. Unabhängig davon, ob Sie asynchronarbeiten oder nicht, ist das Akzeptieren eines CancellationToken als Parameter für Ihre Methode ein großartiges Muster, um ihrem Aufrufer zu ermöglichen, verlorenes Interesse am Ergebnis auszudrücken. Die Stornierung von Coroutine ist kooperativ. Ein Coroutine-Code muss zusammenarbeiten, um kannbar sein.
Alle Aussetzensfunktionen in kotlinx.coroutines sind stornierbar. Sie überprüfen auf Stornierung von Coroutine und werfen CancellationException aus, wenn sie storniert werden. Wenn jedoch eine Coroutine in einer Berechnung arbeitet und nicht auf Abbruch überprüft, kann sie nicht abgebrochen werden, wie das folgende Beispiel zeigt: yield cancel(task) löst einen Abbruch bei Subtask aus, was wiederum einen Abbruch bei subtask2 auslöst. 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. Unter der Haube benachrichtigt der Kinderjob seine Eltern über die Kündigung über die Ausnahme. Das übergeordnete Element verwendet die Ursache des Abbruchs, um zu bestimmen, ob es die Ausnahme behandeln muss. Wenn das Kind aufgrund von CancellationException abgebrochen wurde, ist keine andere Aktion für das übergeordnete Element erforderlich.
Die Klassen System.Threading.Tasks.Task und System.Threading.Tasks.Task unterstützen den Abbruch durch die Verwendung von Abbruchtoken in .NET Framework. Weitere Informationen finden Sie unter Abbrechen in verwalteten Threads. In den Aufgabenklassen umfasst der Abbruch die Zusammenarbeit zwischen dem Benutzerdelegat, der einen abbruchfähigen Vorgang darstellt, und dem Code, der den Abbruch angefordert hat. Ein erfolgreicher Abbruch umfasst den anfordernden Code, der die CancellationTokenSource.Cancel-Methode aufruft, und der Benutzerdelegat, der den Vorgang rechtzeitig beendet. Sie können den Vorgang mit einer der folgenden Optionen beenden: Angenommen, Sie möchten eine bestimmte Aktion ausführen, wenn eine Coroutine abgebrochen wird: Schließen aller möglicherweise verwendenden Ressourcen, Protokollieren des Abbruchs oder eines anderen Bereinigungscodes, den Sie ausführen möchten. Es gibt mehrere Möglichkeiten, dies zu tun: Durch Auslösen einer OperationCanceledException und Übergeben des Tokens, für das der Abbruch angefordert wurde. Die bevorzugte Methode hierfür ist die Verwendung der ThrowIfCancellationRequested-Methode. Eine Aufgabe, die auf diese Weise abgebrochen wird, wechselt in den Status Abgebrochen, den der aufrufende Code verwenden kann, um zu überprüfen, ob die Aufgabe auf ihre Abbruchanforderung geantwortet hat. Hier verwenden wir eine TaskCompletionSource, um die zugrunde liegende LongRunningOperation zu umschließen. Sie unterstützen die Stornierung, und genau das ist es, was wir brauchen, um einen nicht kanzellenbaren Vorgang in einen kanzellenbaren vorgangsweise umzuwandeln. Es gibt natürlich andere Möglichkeiten, dasselbe zu erreichen.
Aber ich mag dieses, es ist sauber und asynchron warten freundlich.