In der kotlinx.coroutines
Bibliothek können Sie eine neue Coroutine entweder mit launch
(mit join
) oder async
(mit await
) starten . Was ist der Unterschied zwischen ihnen?
quelle
In der kotlinx.coroutines
Bibliothek können Sie eine neue Coroutine entweder mit launch
(mit join
) oder async
(mit await
) starten . Was ist der Unterschied zwischen ihnen?
launch
wird verwendet, um Coroutine zu feuern und zu vergessen . Es ist wie ein neuer Thread. Wenn der Code in der launch
Datei mit Ausnahme beendet wird, wird er in einem Thread wie eine nicht erfasste Ausnahme behandelt - normalerweise in JVM-Backend-Anwendungen auf stderr gedruckt und stürzt Android-Anwendungen ab. join
wird verwendet, um auf den Abschluss der gestarteten Coroutine zu warten und ihre Ausnahme nicht weiterzugeben. Allerdings ist ein abgestürzt Kind bricht Koroutine seine Eltern mit der entsprechenden Ausnahme, auch.
async
wird verwendet, um eine Coroutine zu starten, die ein Ergebnis berechnet . Das Ergebnis wird durch eine Instanz dargestellt Deferred
und Sie müssen verwenden await
darauf. Eine nicht erfasste Ausnahme im async
Code wird im Ergebnis gespeichert Deferred
und nirgendwo anders geliefert. Sie wird stillschweigend gelöscht, sofern sie nicht verarbeitet wird. Sie dürfen die Coroutine, die Sie mit Async begonnen haben, NICHT vergessen .
Ich finde diesen Leitfaden https://github.com/Kotlin/kotlinx.coroutines/blob/master/coroutines-guide.md nützlich. Ich werde die wesentlichen Teile zitieren
🦄 Coroutine
Sie können sich Coroutine also als etwas vorstellen, das Threads auf sehr effiziente Weise verwaltet.
🐤 starten
So
launch
startet einen Hintergrund - Thread, etwas tut, und gibt eine sofort als TokenJob
. Sie können dies aufrufen,join
umJob
zu blockieren, bis dieserlaunch
Thread abgeschlossen ist🦆 async
So
async
startet einen Hintergrund - Thread, etwas tut, und gibt eine sofort als TokenDeferred
.Also
Deferred
ist eigentlich einJob
. Siehe https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/-deferred/index.html🦋 Async ist standardmäßig eifrig
quelle
launch
undasync
werden verwendet, um neue Coroutinen zu starten. Sie führen sie jedoch auf unterschiedliche Weise aus.Ich möchte ein sehr einfaches Beispiel zeigen, das Ihnen hilft, Unterschiede sehr leicht zu verstehen
In diesem Beispiel lädt mein Code 3 Daten per
btnCount
KnopfdruckpgBar
herunter und zeigt den Fortschrittsbalken an, bis der gesamte Download abgeschlossen ist. Es gibt 3suspend
FunktionendownloadTask1()
,downloadTask2()
unddownloadTask3()
welche die Download - Daten. Um es zu simulieren, habe ichdelay()
in diesen Funktionen verwendet. Diese Funktionen warten5 seconds
,8 seconds
und5 seconds
jeweils.Da wir
launch
diese Suspend-Funktionen zum Starten verwendet haben,launch
werden sie nacheinander (einzeln) ausgeführt . Dies bedeutet, dassdownloadTask2()
der Start nachdownloadTask1()
Abschluss unddownloadTask3()
erst nachdownloadTask2()
Abschluss beginnen würde.Wie im Ausgabe-Screenshot würde die
Toast
Gesamtausführungszeit zum Abschließen aller 3 Downloads zu 5 Sekunden + 8 Sekunden + 5 Sekunden = 18 Sekunden mit führenlaunch
Wie wir gesehen haben,
launch
ist die Ausführungsequentially
für alle 3 Aufgaben möglich. Die Zeit, um alle Aufgaben zu erledigen, war18 seconds
.Wenn diese Aufgaben unabhängig sind und das Berechnungsergebnis anderer Aufgaben nicht benötigen, können sie ausgeführt werden
concurrently
. Sie würden zur gleichen Zeit starten und gleichzeitig im Hintergrund laufen. Dies kann mit gemacht werdenasync
.async
Gibt eine Instanz vomDeffered<T>
Typ zurück, wobeiT
es sich um den Datentyp handelt, den unsere Suspend-Funktion zurückgibt. Beispielsweise,downloadTask1()
würde zurückgeben,Deferred<String>
da String der Rückgabetyp der Funktion istdownloadTask2()
würde zurückkehren,Deferred<Int>
da Int der Rückgabetyp der Funktion istdownloadTask3()
würde zurückkehren,Deferred<Float>
da Float der Funktionstyp return istWir können das Rückgabeobjekt vom
async
Typ verwendenDeferred<T>
, um den zurückgegebenen Wert vom TypT
abzurufen. Das kann mitawait()
Anruf gemacht werden. Überprüfen Sie zum Beispiel den folgenden CodeAuf diese Weise haben wir alle drei Aufgaben gleichzeitig gestartet. Meine gesamte Ausführungszeit wäre also nur
8 seconds
die Zeit, fürdownloadTask2()
die es die größte aller drei Aufgaben ist. Sie können dies im folgenden Screenshot in sehenToast message
quelle
launch
für sequentielle Spaß ist, währendasync
für gleichzeitigelaunch
undasync
wird neue Coroutinen starten. Sie vergleichen eine einzelne Coroutine ohne Kinder mit einer einzelnen Coroutine mit 3 Kindern. Sie könnten jeden derasync
Aufrufe durch ersetzen,launch
und in Bezug auf die Parallelität würde sich absolut nichts ändern.Beide Coroutine-Builder, nämlich launch und async, sind im Grunde genommen Lambdas mit einem Empfänger vom Typ CoroutineScope, was bedeutet, dass ihr innerer Block als Suspend-Funktion kompiliert wird. Daher werden beide in einem asynchronen Modus ausgeführt UND beide führen ihren Block nacheinander aus.
Der Unterschied zwischen Start und Async besteht darin, dass sie zwei verschiedene Möglichkeiten ermöglichen. Der Launch Builder gibt einen Job zurück, die asynchrone Funktion gibt jedoch ein zurückgestelltes Objekt zurück. Sie können launch verwenden, um einen Block auszuführen, von dem Sie keinen zurückgegebenen Wert erwarten, dh in eine Datenbank schreiben oder eine Datei speichern oder etwas verarbeiten, das im Grunde nur als Nebeneffekt bezeichnet wird. Auf der anderen Seite gibt Async, das ein Zurückgestelltes zurückgibt, wie ich zuvor angegeben habe, einen nützlichen Wert aus der Ausführung seines Blocks zurück, ein Objekt, das Ihre Daten umschließt, sodass Sie es hauptsächlich für das Ergebnis, möglicherweise aber auch für die Nebenwirkung verwenden können. NB: Sie können den verzögerten Wert entfernen und seinen Wert mit der Funktion wait abrufen, die die Ausführung Ihrer Anweisungen blockiert, bis ein Wert zurückgegeben oder eine Ausnahme ausgelöst wird!
Beide Coroutine Builder (Start und Async) können abgebrochen werden.
Noch etwas?: Ja, wenn beim Start eine Ausnahme innerhalb ihres Blocks ausgelöst wird, wird die Coroutine automatisch abgebrochen und die Ausnahmen werden zugestellt. Wenn dies andererseits mit Async geschieht, wird die Ausnahme nicht weiter verbreitet und sollte innerhalb des zurückgegebenen zurückgestellten Objekts abgefangen / behandelt werden.
Weitere Informationen zu Coroutinen finden Sie unter https://kotlinlang.org/docs/tutorials/coroutines/coroutines-basic-jvm.html https://www.codementor.io/blog/kotlin-coroutines-6n53p8cbn1
quelle
Start gibt einen Job zurück
async gibt ein Ergebnis zurück (verzögerter Job)
Beim Starten mit Join wird gewartet, bis der Job abgeschlossen ist. Der Coroutine-Aufruf join () wird einfach angehalten, sodass der aktuelle Thread in der Zwischenzeit andere Arbeiten ausführen kann (z. B. das Ausführen einer anderen Coroutine).
Async wird verwendet, um einige Ergebnisse zu berechnen. Es erstellt eine Coroutine und gibt das zukünftige Ergebnis als Implementierung von Deferred zurück. Die laufende Coroutine wird abgebrochen, wenn die resultierende Verzögerung abgebrochen wird.
Stellen Sie sich eine asynchrone Methode vor, die einen Zeichenfolgenwert zurückgibt. Wenn die asynchrone Methode ohne Warten verwendet wird, wird eine verzögerte Zeichenfolge zurückgegeben. Wenn jedoch Warten verwendet wird, erhalten Sie als Ergebnis eine Zeichenfolge
Der Hauptunterschied zwischen Async und Start. Deferred gibt einen bestimmten Wert vom Typ T zurück, nachdem Ihre Coroutine die Ausführung abgeschlossen hat, Job hingegen nicht.
quelle
Async vs Launch Async vs Launch Diff Image
Start / Async kein Ergebnis
asynchron für Ergebnis
quelle