Hur avbrytning sprids i coroutine-hierarkier
Förstå hur avbrytning sprids genom relationer mellan överordnade och underordnade coroutines.
Hur avbrytning sprids i coroutine-hierarkier är en gratis lektion i Kotlin Academy på CoddyKit. Detta är lektion 4 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Kotlin Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Kotlin Academy innehåller totalt 4 lektioner.
Relationen mellan förälder och barn
När en coroutine startar en annan med launch ansluter sig barnet till förälderns Job. Om föräldern avbryts avbryts alla barn.
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")
}Ett barnfel avbryter föräldern
Om ett barn kastar ett undantag som inte beror på avbrytning avbryter det föräldern och alla syskon — detta är standardbeteendet för 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}")
}
}Avbrytning propagerar inte uppåt
Att avbryta ett barn avbryter INTE föräldern. Det är bara ohanterade undantag som gör det. En förälder kan när som helst avbryta ett barn.
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 jämfört med GlobalScope
coroutineScope skapar ett underordnat scope: avbrytningar och fel propagerar. GlobalScope skapar föräldralösa coroutines utan förälder — undvik det i produktion.
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
}Avbryta ett delträd
Varje launch eller async returnerar ett Job. Avbryt ett jobb för att avbryta hela dess delträd, inklusive eventuella kapslade starter.
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() efter cancel()
Anropa alltid join() efter cancel() för att vänta på att coroutinen och dess barn har stoppats helt innan du fortsätter.
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() är en bekvämlighetsfunktion som först avbryter och sedan ansluter, vilket motsvarar 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")
}Propagering genom async
Med async lagras undantag i Deferred och kastas när du anropar await(). De propagerar fortfarande till föräldern om de inte hanteras.
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}")
}
}Garantin för strukturerad samtidighet
Strukturerad samtidighet garanterar att alla barn har slutförts när ett scope avslutas. Inga coroutines läcker — antingen slutförs de eller så avbryts de.
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")
}Diagram över avbrytningens propagering
Hierarkin: avbrytning av förälder → alla barn avbryts. Avbrytning av barn → endast det delträdet. Undantag i barn → föräldern avbryts → syskon avbryts.
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()
}CoroutineScope-livscykeln i Android
I Android avbryts viewModelScope när ViewModel rensas bort. Alla startade coroutines avbryts automatiskt — ingen manuell rensning behövs.
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()") }Snabb kontroll
Vad händer med syskons-coroutines när ett barn kastar ett ohanterat undantag under ett vanligt Job?
Sammanfattning
Avbrytning av föräldern sprids till alla barn. Fel i ett barn propagerar till föräldern och syskonen (med ett vanligt Job). Använd cancelAndJoin() för en ordnad nedstängning. Strukturerad samtidighet säkerställer att inga coroutines läcker.
Lär dig Kotlin med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 51
- Lektioner
- 203
Vanliga frågor
Är lektionen ”Hur avbrytning sprids i coroutine-hierarkier” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Kotlin Academy, inklusive ”Hur avbrytning sprids i coroutine-hierarkier”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Kotlin Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Hur avbrytning sprids i coroutine-hierarkier”?
Förstå hur avbrytning sprids genom relationer mellan överordnade och underordnade coroutines. Ni övar på Kotlin Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Kotlin Academy?
Du behöver inga förkunskaper. Utbildningen i Kotlin Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 4 av 4.
Hur lång tid tar lektionen ”Hur avbrytning sprids i coroutine-hierarkier”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Kotlin Academy-lektionen?
Ja. Varje Kotlin Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Kooperativ avbrytning: isActive och ensureActive
- withTimeout och withTimeoutOrNull
- Rensa upp med finally och NonCancellable
- Hur avbrytning sprids i coroutine-hierarkier