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

问题描述 投票:0回答:1

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

kotlin exception kotlin-coroutines coroutine
1个回答
0
投票

好的,我明白了。这是因为 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 是一个很好的疗法 :)

© www.soinside.com 2019 - 2024. All rights reserved.