[英]CoroutineScope with SupervisorJob vs supervisorScope
最近我一直在详细学习协程,据我所知,如果协程的一个子进程由于某种原因被取消, SupervisorJob()
给了我们不取消所有子进程的机会。
据说以 coroutineScope 启动的coroutineScope
如果失败会取消所有子进程,但以supervisorScope
启动的协程只会取消失败的子进程
我想知道我是否可以通过将SupervisorJob
作为 CoroutineContext 添加到它来更改CoroutineScope
的行为,但是我无法获得预期的行为,这是我没有得到的
预期行为 - 打印 getData1() 和 getData3() 结果*
实际:- getData2() 取消所有协程
fun main() = runBlocking {
val exceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable ->
println(throwable)
}
val customScope = CoroutineScope(SupervisorJob() + exceptionHandler)
customScope.launch {
launch {
getData1().also { println(it) }
}
launch {
getData2().also { println(it) }
}
launch {
getData3().also { println(it) }
}
}.join()
}
private suspend fun getData1(): String? {
delay(1000)
return "data 1"
}
private suspend fun getData2(): String? {
delay(300)
throw RuntimeException("While getting Data 2 exception happened")
}
private suspend fun getData3(): String? {
delay(800)
return "data 3"
}
您没有在customScope
中启动三个内部协程。 您在已启动的外部协程的 scope 中启动它们(通过使用隐式this
来启动它们)。 如果您从具有 SupervisorJob 的自定义 scope 启动它们,那么它应该可以工作:
launch {
listOf(
customScope.launch {
getData1().also { println(it) }
},
customScope.launch {
getData2().also { println(it) }
},
customScope.launch {
getData3().also { println(it) }
}
).joinAll()
}.join()
SupervisorJob 预期的行为,发生在我们使用来自根 scope 的 lunch/async 调用它时。
val job1 =rootscope.lunch{}
val job2 =rootscope.lunch{}
val job3 =rootscope.lunch{}
如果其中一项工作失败,它不会影响其他工作,但是如果我们将它用作孩子,它的行为就像您的示例中的 Job() 一样。
但是,如果我需要孩子的协程表现得像“如果它从根作用域吃午饭”呢? . 就像你的例子,然后 supervisorScope 似乎解决了这个问题,如果你使用:
customScope.launch {
supervisorScope {
launch {
throw Exception()
}
launch {
println("hjkhjk 111")
}
launch {
println("hjkhjk 222")
}
}
}.join()
然后每个子协程都以 rootScope.lunch{...} 运行,你的问题就解决了
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.