CancellationException
是一种特殊的异常,用于标识协程的取消状态。当协程被取消时,会抛出此异常,提示协程应该尽快停止执行。
当捕获 CancellationException
时,如果不重新抛出它,协程框架可能不会意识到协程已经被取消,这会导致协程无法正常终止,甚至影响到其他协程和任务的执行。
示例
以下示例,展示如何捕获并重新抛出 CancellationException
:
import kotlinx.coroutines.*
fun main() = runBlocking {
val job = launch {
try {
repeat(1000) { i ->
println("Job: I'm sleeping $i ...")
delay(500L)
}
} catch (e: CancellationException) {
println("Job was cancelled")
throw e // 重新抛出 CancellationException
} finally {
println("Job: I'm running finally")
}
}
delay(1300L) // 等待一段时间
println("Main: I'm tired of waiting!")
job.cancelAndJoin() // 取消任务并等待它完成
println("Main: Now I can quit.")
}
使用 ensureActive
可以确保协程在被取消时正确地终止:
import kotlinx.coroutines.*
fun main() = runBlocking {
val job = launch {
try {
while (isActive) {
// 协程工作
}
} catch (e: Exception) {
println("Caught exception: ${e.message}")
if (e is CancellationException) {
throw e // 重新抛出 CancellationException
}
} finally {
ensureActive() // 确保协程正确终止
println("Job: I'm running finally")
}
}
delay(1000L)
println("Main: Cancelling job")
job.cancelAndJoin() // 取消并等待任务完成
println("Main: Job cancelled")
}
结论
在 Kotlin 协程中,捕获并重新抛出 CancellationException
是确保协程正确取消的关键步骤。如果忽略这一点,可能会导致协程未能按预期终止,从而影响应用的稳定性和性能。