取消孩子如何在Kotlin协同工作?

根据文档cancelChildren应该取消一个协程的孩子,但离开父母不受影响(“这个工作本身的状态不受影响。”)但是,如果我有代码

val outer = launch { try { launch (coroutineContext) { try { // work here } catch (ex: Exception) { println("In inner catch") } finally { println("In inner finally") } } delay(5000) // so the outer job is running when I cancel it } catch (ex: CancellationException) { println("In outer catch") } finally { println("In outer finally") } } delay(100) // give it a chance to run outer.cancelChildren() 

然后我看到以下

 In inner catch In inner finally In outer catch In outer finally 

为什么“外部”工作被取消?

如果我打电话给outer.cancel(但我期望),这是完全相同的行为,

您在外部协程中的delay(5000)是可取消的,因此受到outer.cancelChildren()影响。 它会引发在外部try看到的CancellationExceptioncancelChildren函数不会取消外部作业,通过在调用之后检查outer.isCancelled可以使其显而易见。

如果从代码中删除delay调用,则会打印预期的结果。 请注意,协程会反过来等待他们的孩子,延迟是没有必要的:

父协程总是等待所有的孩子完成。 Parent不必显式地跟踪它启动的所有子项,也不必使用Job.join等待它们。