协程进阶:06. 不可取消的任务块

本篇解析 example-cancel-06.kt,介绍如何在协程取消后运行挂起逻辑。

1. 核心问题

finally 块中,如果你需要调用一个挂起函数(例如 delay 或关闭网络连接),由于协程已经是“已取消”状态,挂起函数会直接抛出异常,导致清理逻辑中断。

2. 解决方案:withContext(NonCancellable)

使用 withContext(NonCancellable) 可以创建一个临时作用域,该作用域会忽略当前的取消信号,确保内部逻辑完整执行。

代码解析

1
2
3
4
5
6
7
finally {
withContext(NonCancellable) {
println("I am running finally")
delay(1000L) // 这里的延迟会生效,不会被取消
println("Cleanup done after 1 second")
}
}

3. 开发者感悟

NonCancellable 只应该用于 finally 块中的资源释放或记录日志。不要滥用它来执行长期的业务逻辑,否则会破坏协程的响应性。

,