【问题标题】:How Should cancelChildren work in Kotlin Coroutines?在 Kotlin 协程中 cancelChildren 应该如何工作?
【发布时间】:2018-06-03 03:56:57
【问题描述】:

根据文档,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 时得到的行为完全相同(但我希望如此)

【问题讨论】:

    标签: kotlin kotlinx.coroutines


    【解决方案1】:

    您在外部协程中的delay(5000) 是可取消的,因此受到outer.cancelChildren() 的影响。它抛出在外部try 中看到的CancellationExceptioncancelChildren 函数不会取消外部作业,调用后检查outer.isCancelled 可以明显看出这一点。

    如果从代码中删除delay 调用,它会打印预期的结果。注意协程等待他们的孩子anyway,延迟不是必须的:

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

    【讨论】:

    • 谢谢,现在说得通了。挂起函数(延迟、加入...)传播了我没有意识到的 CancellationException。这是有道理的,因为“父母”应该知道“孩子”已被取消
    • 是的,正是:-)
    猜你喜欢
    • 2019-04-30
    • 2021-08-01
    • 2020-09-15
    • 1970-01-01
    • 2020-10-08
    • 2021-10-27
    • 2019-08-08
    • 2021-05-01
    • 2020-06-07
    相关资源
    最近更新 更多