gpt4 book ai didi

kotlin - 将协程上下文显式传递给异步调用会产生不同的异常处理行为,与将其安装在封闭范围内

转载 作者:行者123 更新时间:2023-12-02 12:41:17 26 4
gpt4 key购买 nike

下面的代码输出“由异常处理程序处理”和“捕获的异常”消息:

import kotlin.coroutines.*
import kotlinx.coroutines.*

fun main() {
val eh = CoroutineExceptionHandler { _, e -> println("Handled by exception handler") }
val context = eh + Job()

CoroutineScope(context).launch {
val res = async<String> { throw RuntimeException() }
// val res = async<String>(context) { throw RuntimeException() }

try {
println("Result: ${res.await()}")
}
catch (e: Throwable){
println("Caught exception")
}
}


Thread.sleep(1000)
}

但是,如果我在其中注释了“val res”行,则只会收到“捕获的异常”消息。为什么向 async显式提供CoroutineContext(包括异常处理程序)会导致异常处理程序无法处理异常?

最佳答案

答案隐藏在here文档中:

Normally, uncaught exceptions can only result from coroutines created using the launch builder. A coroutine that was created using async always catches all its exceptions and represents them in the resulting Deferred object.



here:

The parent job is inherited from a CoroutineScope as well, but it can also be overridden with corresponding coroutineContext element.



在第一种情况下:
val res = async<String> { throw RuntimeException() }

Kotlin通过添加新的 Job实例来创建新协程的上下文,该实例是通过协程范围继承的作业的子级。因此,当此协程失败时,它将通知其父级,然后将其带到已安装的异常处理程序。

在第二种情况下:
val res = async<String>(context) { throw RuntimeException() }
context已经包含 Job元素。这将覆盖上面的行为,并且不会为新协程创建任何新作业。因此,它的 Job元素没有指向范围的父项。当失败时,协程不会按照引用的文档将异常传递给处理程序,也不会将异常传递给不存在的父级。

经验教训:切勿将带有 Job元素的上下文传递给子 async构建器。

关于kotlin - 将协程上下文显式传递给异步调用会产生不同的异常处理行为,与将其安装在封闭范围内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58805372/

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