首页 > 解决方案 > 对于 Kotlin Coroutine,使用 CoroutineScope 启动时,parentJob 放在哪里?

问题描述

我在博客中看到https://medium.com/capital-one-tech/coroutines-and-rxjava-an-asynchronicity-comparison-part-2-cancelling-execution-199485cdf068

launch(parentJob + CommonPool) {
   // my suspending block
}

然后我们可以在最后取消作业 ie parentJob.cancel(),因此作业launch也将被取消。

但是,如果我使用 CoroutineScope 如下启动它,我应该把我的parentJob?

CoroutineScope(Dispatchers.IO + parentJob).launch{ 
   // ...
}

或者

CoroutineScope(Dispatchers.IO).launch(parentJob) {
   // ...
}

或者以上两个也是错误的?

标签: kotlincoroutinekotlin-coroutinescoroutinescope

解决方案


使用第一种方法时

val parentJob = Job()
val scope = CoroutineScope(Dispatchers.IO + parentJob)

scope.launch { 
    // will be cancelled
    // ...
}
scope.launch {
    // ...
    // will be cancelled
    launch {
        // will be cancelled
    }
}
scope.launch(NonCancellable) {
    // won't be cancelled now
}
parentJob.cancel()

使用范围启动的所有协程都将附加作业,除非某些协程通过将作业传递给协程(如launchor )来覆盖它async。因此,这样做job.cancel()将取消使用范围启动的所有正在运行的协程。

使用第二种方法时

val parentJob = Job()
val scope = CoroutineScope(Dispatchers.IO)
scope.launch(parentJob) {
    // will be cancelled
    launch {
        // will be cancelled
    }
}
scope.launch {
    // ...
    // this one won't be cancelled
}
parentJob.cancel()

父作业仅适用于使用launch. 所以只有那个协程和它的子协程会被取消,范围内的其他协程不会被取消作业而取消。


推荐阅读