gpt4 book ai didi

asynchronous - 在Kotlin异步协程中捕获异常并停止传播

转载 作者:行者123 更新时间:2023-12-02 13:11:36 27 4
gpt4 key购买 nike

我想捕捉异步协程抛出的异常。
以下代码演示了一个问题:

import kotlinx.coroutines.*

fun main() = runBlocking<Unit> {
try {
println(failedConcurrentSum())
} catch (e: ArithmeticException) {
println("Computation failed with ArithmeticException")
}
}

suspend fun failedConcurrentSum() = coroutineScope {
try {
val one = async {
try {
delay(1000L)
42
} finally {
println("First child was cancelled")
}
}

val two = async<Int> {
println("Second child throws an exception")
throw ArithmeticException()
}

one.await() + two.await()
} catch (e: ArithmeticException) {
println("Using a default value...")
0
}
}

打印:
Second child throws an exception
First child was cancelled
Computation failed with ArithmeticException
try-catch中的 failedConcurrentSum不处理 val two引发的异常。
我可以说服自己,这是由于“结构化并发”所致。

但是,这并不能解释为什么将 async包裹在 coroutineScope中会捕获异常:

suspend fun failedConcurrentSum() = coroutineScope {
try {
val one = coroutineScope {
async {
try {
delay(1000L)
42
} finally {
println("First child was cancelled")
}
}
}

val two = coroutineScope {
async<Int> {
println("Second child throws an exception")
throw ArithmeticException()
}
}

one.await() + two.await()
} catch (e: ArithmeticException) {
println("Using a default value...")
0
}
}

打印:
First child was cancelled
Second child throws an exception
Using a default value...
0

为什么后者捕获异常而第一个捕获异常?

最佳答案

coroutineScope使用Job

By default, a failure of any of the job’s children leads to an immediate failure of its parent and cancellation of the rest of its children. Job



您可以使用 supervisorScope代替 coroutineScope

A failure or cancellation of a child does not cause the supervisor job to fail and does not affect its other children. SupervisorJob



但您必须等待第一个 async块的完成。

coroutineScope中使用 try catch在发生异常时立即返回默认值
suspend fun failedConcurrentSum() = try {
coroutineScope {
val one = async {
try {
delay(1000L)
42
} finally {
println("First child was cancelled")
}
}

val two = async<Int> {
println("Second child throws an exception")
throw ArithmeticException()
}

one.await() + two.await()
}
} catch (e: ArithmeticException) {
println("Using a default value...")
0
}

关于asynchronous - 在Kotlin异步协程中捕获异常并停止传播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61310030/

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