异步作业取消导致父级取消

时间:2020-03-23 03:45:52

标签: kotlin kotlin-coroutines

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

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

发生了什么事?

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
}

}

1 个答案:

答案 0 :(得分:2)

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

您可以按this article阅读Roman Elizarov关于该主题的信息。