【发布时间】:2020-04-19 19:03:45
【问题描述】:
我想捕获异步协程抛出的异常。 下面的代码演示了一个问题:
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
failedConcurrentSum 中的try-catch 不处理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
为什么后者捕获异常而第一个没有?
【问题讨论】:
标签: asynchronous kotlin kotlin-coroutines