Careeroza
Cleanup with finally and NonCancellable
finally Runs on Cancel
Because cancellation is an exception, try/finally and use { } work normally: close files, release locks, hide progress bars.
But inside finally of a cancelled coroutine, any suspend call throws CancellationException again. If cleanup must suspend (e.g. save to DB, tell the server), wrap it in withContext(NonCancellable).
Example
Example
import kotlinx.coroutines.*
fun main() = runBlocking {
val job = launch {
try {
repeat(10) { i ->
println("Uploading part $i")
delay(100)
}
} finally {
println("finally: hide progress bar")
try {
delay(10) // suspending in a cancelled coroutine
println("never printed")
} catch (e: CancellationException) {
println("finally: plain delay was cancelled")
}
withContext(NonCancellable) {
delay(50)
println("finally: saved draft to DB (NonCancellable)")
}
}
}
delay(150)
job.cancelAndJoin()
println("Done")
}Output
Uploading part 0 Uploading part 1 finally: hide progress bar finally: plain delay was cancelled finally: saved draft to DB (NonCancellable) Done
Note: Use NonCancellable only for short cleanup, never with launch(NonCancellable) for normal work: it breaks structured concurrency.