gpt4 book ai didi

android - 与 SupervisorJob 的协程 - 取消行为

转载 作者:太空狗 更新时间:2023-10-29 13:44:10 26 4
gpt4 key购买 nike

我需要在我的代码中实现一些异常处理,所以我有以下从 fragment 启动的协程测试代码;

private val scoped = CoroutineScope(Dispatchers.Default + SupervisorJob())

...

val handler = CoroutineExceptionHandler { _, exception ->
println("TAG-Caught $exception")
}

scoped.launch(handler) {

val job1 = launch {
println("TAG-first job is running")
delay(200)
}

testParentChildWithExceptionWithSupervision()

launch {
println("TAG-third job is running")
}
}

testParentChildWithExceptionWithSupervision 方法的样子;

suspend fun testParentChildWithExceptionWithSupervision() {

supervisorScope {

val job1 = launch {
println("TAG-running first (inner) child")
delay(200)
throw ArithmeticException()
}

val job2 = launch {
job1.join()
println("TAG-First child is cancelled: ${job1.isCancelled}, but second one is still active")
delay(200)
}

job1.join()
println("TAG-second child is cancelled: ${job2.isCancelled}")

println("TAG-ENDING")
}
}

输出如我所料;

enter image description here

问题是,一旦我在挂起函数中将 supervisorScope 更改为 coroutineScope,我就会看到根范围(带有 SpervisorJob)不会继续处理她的 child ;

suspend fun testParentChildWithExceptionWithoutSupervision() {

coroutineScope {

val job1 = launch {
println("HH-doing first child")
delay(200)
throw ArithmeticException()
}

val job2 = launch {
job1.join()
println("HH-First child is cancelled: ${job1.isCancelled}, but second one is still active")
delay(200)
}

我得到的是这个输出;

enter image description here

所以即使范围有主管工作,在出现异常后似乎没有任何事情在根范围内进行。我敢打赌我想念某事但看不到它。有人可以解释一下背后的原因吗?

最佳答案

如果您查看 documentationsuspend fun coroutineScope 上,您会发现:

The method may throw a [...] corresponding unhandled Throwable if there is any unhandled exception in this scope (for example, from a crashed coroutine that was started with launch in this scope).

这就是您的代码中发生的情况:“第一个(内部)子级”因未处理的 ArithmeticException 而崩溃。这成为 testParentChildWithExceptionWithSupervision 的结果,并且在调用站点,没有任何处理它。因此,它也会让父进程崩溃——不是通过传播协程取消的机制,而是通过基本的异常机制。 SupervisorJob 在这里没有区别,主要代码块突然完成,但未处理该异常,这就是为什么您看到它由未处理的异常处理程序打印出来的原因。

如果您修改代码来执行此操作:

    try {
testParentChildWithExceptionWithSupervision()
} catch (e: ArithmeticException) {
println("ArithmeticException in main block")
}

您会看到主协程一直执行到最后。

关于android - 与 SupervisorJob 的协程 - 取消行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57355973/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com