Kotlin

Coroutine Cancellation

admin by @admin ADMIN
Jun 13, 2026
Jun 1, 2026
Public
0 0 up · 0 down Sign in to vote
Cancellation is cooperative — your coroutine must check via `ensureActive()`, `yield()`, or any other suspending call. CPU-busy loops without a suspend point are NOT cancellable.
Kotlin
Raw
import kotlinx.coroutines.*

fun main() = runBlocking {
    // Cooperative — uses delay() which checks for cancellation
    val job1 = launch {
        repeat(100) { i ->
            println("polite: $i")
            delay(50)               // cancellation checkpoint
        }
    }
    delay(180)
    job1.cancel()
    job1.join()

    // BAD — no suspend points, won't cancel
    val job2 = launch {
        var i = 0
        while (i < 1_000_000_000) {
            i++                     // tight CPU loop, no cancellation check
            if (i % 100_000_000 == 0) println("loop: $i")
        }
        println("finished loop")
    }
    delay(50)
    job2.cancel()                   // ignored
    job2.join()                     // waits for the whole loop to finish

    // FIX — sprinkle ensureActive() or yield() inside CPU loops
    val job3 = launch {
        var i = 0
        while (i < 1_000_000_000) {
            i++
            if (i % 100_000 == 0) ensureActive()    // throws on cancel
        }
    }
    delay(20)
    job3.cancelAndJoin()
    println("job3 cancelled")
}
Tags

Save your own code snippets

Create a free account and build your private vault. Share publicly whenever you want.