gpt4 book ai didi

kotlin - 为什么挂起函数在finally中会抛出异常

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

正如标题所说,为什么挂起函数会在finally中抛出异常?

对于常规函数,finally block 会执行所有函数:

import kotlinx.coroutines.*

fun main() {
val handler = CoroutineExceptionHandler { _, exception ->
println("Caught $exception")
}
val job = GlobalScope.launch(handler) {
launch {
// the first child
try {
println("inside try")
delay(1000)
} finally {

println("Children are cancelled, but exception is not handled until all children terminate")

Thread.sleep(1000)
println("thread.sleep executed")
//foo()
println("The first child finished its non cancellable block")

}
}
launch {
// the second child
delay(10)
println("Second child throws an exception")
throw ArithmeticException()
}
}

Thread.sleep(1000000)
println("complete")
}

例如,当我执行 Thread.sleep(1000) 时,它会打印:

"The first child finished its non cancellable block"

但是如果我将该行更改为 delay(1000),则不会。

根据我的理解,在finally block 中,异常(如果存在)会在执行整个 block 后抛出。

但在这种情况下,delay 会导致提前抛出此异常。

另一方面,Thread.sleep 则不然。

谁能帮忙解释一下吗?

最佳答案

Kotlin 中的挂起函数与阻塞函数的工作方式不同。当您取消作业时,在取消后的第一次暂停时,即使您位于finally block 中,执行也会停止。如果您在 finally block 中使用 Thread.sleep(1000) 而不是 delay(1000),则不会发生暂停,因为 Thread.sleep()阻塞,而不是挂起,因此整个 finally block 都会被执行。

请注意,在挂起函数内使用阻塞函数是一种反模式,应该避免!!

要在不使用阻塞函数的情况下实现此所需的行为,请使用 withContext(NonCancellable) {...},如所述 here .

您的示例代码应如下所示:

fun main() {
val handler = CoroutineExceptionHandler { _, exception ->
println("Caught $exception")
}
val job = GlobalScope.launch(handler) {
launch {
// the first child
try {
println("inside try")
delay(1000000)
} finally {
withContext(NonCancellable) {
println("Children are cancelled, but exception is not handled until all children terminate")

delay(1000) // This suspension cannot be cancelled
println("delay executed")
//foo()
println("The first child finished its non cancellable block")
}
}
}
launch {
// the second child
delay(10)
println("Second child throws an exception")
throw ArithmeticException()
}
}

Thread.sleep(1000000)
println("complete")
}

输出:

inside try
Second child throws an exception
Children are cancelled, but exception is not handled until all children terminate
delay executed
The first child finished its non cancellable block
Caught java.lang.ArithmeticException

关于kotlin - 为什么挂起函数在finally中会抛出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54965849/

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