应该如何取消孩子们在Kotlin Coroutines工作?

时间:2017-12-20 14:47:01

标签: kotlin kotlinx.coroutines

根据文档,cancelChildren应该取消一个coroutine的孩子,但不要让父母不受影响(“这个工作本身的状态不会受到影响。”)但是,如果我有像

这样的代码
    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(但我希望)

,这就是我得到的完全相同的行为

1 个答案:

答案 0 :(得分:0)

外部协程中的delay(5000)可取消,因此受outer.cancelChildren()影响。它会抛出外部CancellationException中看到的trycancelChildren函数不会取消外部作业,通过在调用后选中outer.isCancelled可以明白这一点。

如果从代码中删除delay调用,则会打印预期结果。请注意,协同程序等待他们的孩子anyway,不需要延迟:

  

父协同程序总是等待所有孩子的完成。 Parent不必显式跟踪它启动的所有子节点,也不必使用Job.join在最后等待它们。