为什么try/catch行为在协程作用域和简单的挂起函数中是不同的(Kotlin)?

w8biq8rn  于 2023-03-09  发布在  Kotlin
关注(0)|答案(1)|浏览(147)

当我尝试在协程上下文中管理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行为不同

ttp71kqs

ttp71kqs1#

好的,我明白了。这是因为try/catch在协程之外。如果我改变try/catch和launch,异常不会杀死协程。

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")
    }
}

抱歉,太明显了。
Tenfour 04在上一个问题中告诉我,但我没有得到。
Stackoverflow是一个很好的治疗:)

相关问题