[英]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.