【问题标题】:Async jobs cancellation causes parent cancellation异步作业取消导致父取消
【发布时间】:2020-03-23 03:45:52
【问题描述】:

我尝试运行两个异步作业。

点击时有一个按钮,将取消其中一项工作。但是我注意到当我这样做时,另一个工作也会被取消。

发生了什么?

class SplashFragment : BaseFragment(R.layout.fragment_splash), CoroutineScope by MainScope() {

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    launch {
        val countdown = async { countDown() }
        val ipAndMaintain = async { checkIPAndMaintain() }

        btnSkip.onClick {
            countdown.cancel() // cancel countdown
            btnSkip.isVisible = false
            if (!ipAndMaintain.isCompleted) {
                showLoadingDialog()
            }
        }
        countdown.await()
        startOtherPage(ipAndMaintain.await())
    }
}

private suspend fun countDown() {
    var time = 3
    while (time >= 0) {
        btnSkip.text = getString(R.string.skip, time)
        delay(1000)
        yield()
        time--
    }
}

private suspend fun checkIPAndMaintain(): Int {
    delay(2000)
    return 1
}

}

【问题讨论】:

    标签: kotlin kotlin-coroutines


    【解决方案1】:

    当您在取消的Deferred 上调用await 时,它会引发异常。如果你没有捕捉到它,那么它将被传播到父协程,这将取消它的所有子协程。用try-catch 块包装你的countdown.await() 指令,你会看到另一个协程继续。这就是结构化并发的效果。

    您可以通过Roman Elizarov 阅读this article 来了解该主题。

    【讨论】:

    • 结构化并发的另一个作用是,如果async { countDown() }失败,也会导致父级及其所有子级被取消,无论你是否从await()捕获异常。跨度>
    • @MarkoTopolnik 知道了。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-14
    • 1970-01-01
    相关资源
    最近更新 更多