0Pricing
Kotlin Academy · Lektion

Abbruchweitergabe in Coroutine-Hierarchien

Verstehen Sie, wie sich Abbrüche durch Eltern-Kind-Beziehungen von Coroutines ausbreiten.

Abbruchweitergabe in Coroutine-Hierarchien ist eine kostenlose Kotlin Academy-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Kotlin Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.

Beziehung zwischen übergeordneter und untergeordneter Coroutine

Wenn eine Coroutine mit launch eine weitere startet, wird das Kind dem Job des Elternteils untergeordnet. Beim Abbruch des Elternteils werden alle Kinder abgebrochen.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val parent = launch {
        launch { delay(1000); println("child 1") }
        launch { delay(1000); println("child 2") }
        delay(1000)
        println("parent")
    }
    delay(50)
    parent.cancel()
    parent.join()
    println("All cancelled")
}

Fehler eines Kindes bricht den Elternteil ab

Wenn ein Kind eine Ausnahme auslöst, die kein Abbruch ist, bricht es den Elternteil und alle Geschwister ab – dies ist das Standardverhalten von Job.

import kotlinx.coroutines.*
fun main() = runBlocking {
    try {
        coroutineScope {
            launch {
                delay(50)
                throw RuntimeException("child failed")
            }
            launch {
                delay(1000)
                println("sibling — never prints")
            }
        }
    } catch (e: RuntimeException) {
        println("Caught: ${e.message}")
    }
}

Ein Abbruch wird nicht nach oben weitergegeben

Der Abbruch eines Kindes bricht den Elternteil NICHT ab. Nur unbehandelte Ausnahmen tun dies. Ein Elternteil kann ein Kind jederzeit abbrechen.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val parent = launch {
        val child = launch {
            delay(1000)
            println("child done")
        }
        delay(50)
        child.cancel()  // cancels child
        child.join()
        println("parent still running")  // parent is fine
    }
    parent.join()
}

coroutineScope im Vergleich zu GlobalScope

coroutineScope erstellt einen untergeordneten Scope: Abbrüche und Fehler werden weitergegeben. GlobalScope erstellt verwaiste Coroutines ohne Elternteil – vermeiden Sie es in Produktionscode.

import kotlinx.coroutines.*
fun main() = runBlocking {
    try {
        coroutineScope {
            launch { delay(50); throw RuntimeException("error") }
        }
    } catch (e: Exception) {
        println("coroutineScope propagated: ${e.message}")
    }
    // GlobalScope.launch { } would NOT propagate to runBlocking
}

Einen Teilbaum abbrechen

Jeder Aufruf von launch oder async gibt einen Job zurück. Brechen Sie einen Job ab, um seinen gesamten Teilbaum einschließlich aller verschachtelten Starts abzubrechen.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val root = launch {
        launch {
            launch { delay(1000); println("deep") }
            delay(1000)
        }
    }
    delay(50)
    root.cancel()
    root.join()
    println("Whole subtree cancelled")
}

join() nach cancel()

Rufen Sie nach cancel() immer join() auf, um auf das vollständige Beenden der Coroutine und ihrer Kinder zu warten, bevor Sie fortfahren.

import kotlinx.coroutines.*
fun main() = runBlocking {
    val job = launch {
        try { delay(1000) }
        finally { println("cleanup ran") }
    }
    delay(50)
    job.cancel()
    job.join()  // waits for finally to complete
    println("Proceeded after join")
}

cancelAndJoin()

job.cancelAndJoin() ist eine praktische Funktion, die zuerst abbricht und anschließend wartet. Sie entspricht cancel() + join().

import kotlinx.coroutines.*
fun main() = runBlocking {
    val job = launch {
        try { delay(1000) }
        finally { println("cleanup") }
    }
    delay(50)
    job.cancelAndJoin()  // cancel + join in one call
    println("Done")
}

Weitergabe über async

Bei async werden Ausnahmen im Deferred gespeichert und ausgelöst, wenn Sie await() aufrufen. Wenn sie nicht behandelt werden, werden sie trotzdem an den Elternteil weitergegeben.

import kotlinx.coroutines.*
fun main() = runBlocking {
    try {
        coroutineScope {
            val d = async { throw RuntimeException("async fail") }
            d.await()  // rethrows here
        }
    } catch (e: RuntimeException) {
        println("Caught from async: ${e.message}")
    }
}

Garantie strukturierter Nebenläufigkeit

Strukturierte Nebenläufigkeit garantiert, dass beim Beenden eines Scopes alle seine Kinder beendet sind. Es bleiben keine Coroutines zurück – sie werden entweder abgeschlossen oder abgebrochen.

import kotlinx.coroutines.*
suspend fun doWork() = coroutineScope {
    launch { delay(100); println("work 1") }
    launch { delay(200); println("work 2") }
    // both children complete before doWork returns
}
fun main() = runBlocking {
    doWork()
    println("All work done")
}

Diagramm zur Weitergabe von Abbrüchen

Die Hierarchie: Elternteil abgebrochen → alle Kinder abgebrochen. Kind abgebrochen → nur dieser Teilbaum. Ausnahme im Kind → Elternteil abgebrochen → Geschwister abgebrochen.

import kotlinx.coroutines.*
fun main() = runBlocking {
    // Parent
    launch {
        val c1 = launch { delay(1000); println("c1") }  // child 1
        val c2 = launch { delay(1000); println("c2") }  // child 2
        delay(50)
        c1.cancel()  // only c1 cancelled
        c1.join()
        println("c2 still active: ${c2.isActive}")
        c2.cancelAndJoin()
    }.join()
}

Lebenszyklus von CoroutineScope in Android

In Android wird viewModelScope abgebrochen, wenn das ViewModel gelöscht wird. Alle gestarteten Coroutines werden automatisch abgebrochen – eine manuelle Bereinigung ist nicht erforderlich.

import kotlinx.coroutines.*
// Pseudocode:
// class MyViewModel : ViewModel() {
//     fun load() = viewModelScope.launch {
//         val data = repo.fetch() // cancelled if VM cleared
//         _state.value = data
//     }
// }
fun main() = runBlocking { println("viewModelScope cancels on ViewModel.onCleared()") }

Kurze Überprüfung

Was geschieht mit Geschwister-Coroutines, wenn ein Kind unter einem regulären Job eine unbehandelte Ausnahme auslöst?

Zusammenfassung

Der Abbruch des Elternteils wird auf alle Kinder übertragen. Fehler eines Kindes werden an den Elternteil und die Geschwister weitergegeben (bei einem regulären Job). Verwenden Sie cancelAndJoin() für ein sauberes Beenden. Strukturierte Nebenläufigkeit verhindert, dass Coroutines zurückbleiben.

Häufig gestellte Fragen

Ist die Lektion „Abbruchweitergabe in Coroutine-Hierarchien“ kostenlos?

Ja — der vollständige Text von „Abbruchweitergabe in Coroutine-Hierarchien“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Kotlin Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Kotlin Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Abbruchweitergabe in Coroutine-Hierarchien“?

Verstehen Sie, wie sich Abbrüche durch Eltern-Kind-Beziehungen von Coroutines ausbreiten. Du übst Kotlin Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Kotlin Academy zu starten?

Keine Vorkenntnisse erforderlich. Kotlin Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.

Wie lange dauert die Lektion „Abbruchweitergabe in Coroutine-Hierarchien“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Kotlin Academy-Lektion Code schreiben und ausführen?

Ja. Jede Kotlin Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Kooperative Abbruchbehandlung: isActive und ensureActive
  2. withTimeout und withTimeoutOrNull
  3. Aufräumen mit finally und NonCancellable
  4. Abbruchweitergabe in Coroutine-Hierarchien
← Zurück zu Kotlin Academy