Careeroza
Cooperative Cancellation
Code Must Check
Cancellation is cooperative: a coroutine stops only when it reaches a suspension point or checks for cancellation. A tight CPU loop that never suspends will ignore cancel().
Example
The first loop never checks, so it runs all 5 steps even after cancel. The second calls ensureActive() and stops.
import kotlinx.coroutines.*
fun main() = runBlocking {
val ignoring = launch(Dispatchers.Default) {
for (step in 0 until 5) {
Thread.sleep(100) // CPU / blocking work, no suspension
println("ignoring: step $step")
}
}
delay(250)
ignoring.cancelAndJoin()
println("--- first job ended")
val cooperative = launch(Dispatchers.Default) {
for (step in 0 until 5) {
ensureActive() // throws if cancelled
Thread.sleep(100)
println("cooperative: step $step")
}
}
delay(250)
cooperative.cancelAndJoin()
println("--- second job ended")
}Output
ignoring: step 0 ignoring: step 1 ignoring: step 2 ignoring: step 3 ignoring: step 4 --- first job ended cooperative: step 0 cooperative: step 1 cooperative: step 2 --- second job ended
Three Ways to Check
| Check | Behaviour |
|---|---|
isActive | property: while (isActive) { ... }, you decide how to stop |
ensureActive() | throws CancellationException if cancelled |
yield() | checks cancellation and lets other coroutines on the same dispatcher run |
Tip: In long loops (parsing a big file, processing 1 lakh rows) call ensureActive() every iteration or every N items.