协程进阶:异常 03. 取消信号与异常传播

本篇解析 example-exceptions-03.kt。探讨取消信号与普通异常在传播上的差异。

1. 核心概念:取消不是失败

在协程中,CancellationException 被视为正常的控制流程,而不是导致程序失败的异常。

传播规则:

  • 向下传播:父协程取消时,所有子协程都会被取消。
  • 不向上传播:子协程被 cancel() 取消时,不会导致父协程被取消。

2. 代码解析

1
2
3
4
5
6
7
8
9
10
11
12
13
val job = launch {
val child = launch {
try {
delay(Long.MAX_VALUE)
} finally {
println("Child is cancelled")
}
}
yield() // 让出执行权,让子协程运行
child.cancel() // 取消子协程
child.join()
println("Parent is not cancelled") // 父协程继续运行
}

3. 开发者感悟

这是一个非常关键的设计。它允许我们在不中断整体任务的情况下,灵活地停止其中的某一部分逻辑。在 Android 中,如果你在一个 Activity 里启动了两个下载任务,取消其中一个任务不应该导致另一个任务也被取消,这就是结构化并发带来的好处。

,