How Does Cancellation Work?
Explore how cancellation works in Kotlin coroutines, including the role of CancellationException, resource cleanup with finally blocks, and safe suspending calls using withContext NonCancellable. Understand how to use invokeOnCompletion for cleanup and handling job states during cancellation.
We'll cover the following...
When a job is canceled, it changes its state to “Canceling.” Then, at the first suspension point, a CancellationException is thrown. We can catch this exception using a try-catch, but it’s recommended to rethrow it.
package kotlinx.coroutines.app
import kotlinx.coroutines.*
suspend fun main(): Unit = coroutineScope {
val job = Job()
launch(job) {
try {
repeat(1_000) { i ->
delay(200)
println("Printing $i")
}
} catch (e: CancellationException) {
println(e)
throw e
}
}
delay(1100)
job.cancelAndJoin()
println("Canceled successfully")
delay(1000)
}Remember that a canceled coroutine is not just stopped—it’s canceled internally using an exception. Therefore, we can freely clean up everything inside the finally block. For instance, we can use a finally block to close a file or a database connection. Since most resource-closing mechanisms rely on the finally block (for example, if we read a file using useLines), we don’t need to ...