当我尝试在协程上下文中管理rethrow时,我终于明白在挂起函数中我们可以像往常一样使用try/catch(感谢@Tenfour04)。
fun main(): Unit = runBlocking {
launch {
doAction()
}
launch {
delay(2000)
println("Printed2")
}
}
suspend fun doAction() {
try {
delay(1000)
throw Error("Some error")
} catch (e: Throwable) { // nope, does not help here
println("Printed1")
}
}
// Printed1
// Printed2
但是让我感到困惑(并让我严重使用 CoroutineExceptionHandler)的是在下面的代码中,try/catch 没有像往常一样工作,因为异常杀死了协程:
fun main(): Unit = runBlocking {
// Don't wrap in a try-catch here. It will be ignored.
try {
launch {
delay(1000)
throw Error("Some error")
}
} catch (e: Throwable) { // nope, does not help here
println("Will not be printed")
}
launch {
delay(2000)
println("Will not be printed")
}
}
// Exception in thread "main" java.lang.Error: Some error...
在这两种情况下,我们都处于协程上下文中。不同之处在于:
我不太清楚为什么两种情况下的 try/catch 行为不同
好的,我明白了。这是因为 try/catch 在协程之外。如果我更改 try/catch 和启动,异常不会杀死协程。
import kotlinx.coroutines.*
import kotlinx.coroutines.runBlocking
fun main(): Unit = runBlocking {
// Don't wrap in a try-catch here. It will be ignored.
launch {
try {
delay(1000)
throw Error("Some error")
} catch (e: Throwable) { // nope, does not help here
println("Will not be printed")
}
}
launch {
delay(2000)
println("Will not be printed")
}
}
对不起,太明显了
Tenfour04在上一个问题中告诉了我,但我没听懂
Stackoverflow 是一个很好的疗法 :)