Handling cancellation, timeouts, and exceptions properly is crucial for building reliable coroutine-based applications. Let’s break down how Kotlin coroutines handle each scenario.
Coroutines in Kotlin are cooperative, meaning they need to actively check for cancellation and respond appropriately.
Coroutines can be cancelled by calling the cancel()
function on a coroutine’s Job.
fun main() = runBlocking {
try {
repeat(1000) { i ->
println("Job: $i")
delay(500) // Suspending function that checks for cancellation
}
} finally {
println("Cleanup")
}
delay(2000) // Let the coroutine run for 2 seconds
println("Cancelling the job")
job.cancel() // Cancel the coroutine
job.join() // Wait for the coroutine to complete
println("Job cancelled")
}
The coroutine checks for cancellation during the delay(500) call.
Without cooperative functions (e.g., delay, yield), the coroutine won’t be cancelled unless you manually handle it.
When a coroutine is cancelled, any cleanup operations (e.g., closing resources) should be performed in the finally block.