【问题标题】:Kotlin: CancellationException unwrapping in coroutinesKotlin:在协程中展开 CancellationException
【发布时间】:2021-06-23 09:24:22
【问题描述】:

我在文档中找到了下一条语句:

取消异常是透明的,默认情况下是展开的:

val handler = CoroutineExceptionHandler { _, exception -> println("CoroutineExceptionHandler got $exception")
}
val job = GlobalScope.launch(handler) {
    val inner = launch { // all this stack of coroutines will get cancelled 
        launch {
            launch {
                throw IOException() // the original exception
            } 
        }
    }
    try {
        inner.join()
    } catch (e: CancellationException) {
        println("Rethrowing CancellationException with original cause")
        throw e // cancellation exception is rethrown, yet the original IOException gets to the handler
    } 
}
job.join()

此文档在此代码中的含义是什么?

2021 年 3 月 27 日更新

import kotlinx.coroutines.*
import java.io.*

fun main() = runBlocking {
    val handler = CoroutineExceptionHandler { _, exception ->
        println("CoroutineExceptionHandler got $exception")
    }
    val job = GlobalScope.launch(handler) {
        launch {
            throw IOException() // the original exception
        }
        launch {
            throw CancellationException("Test", ArithmeticException("Arithmetic"))
        }
    }
    job.join()
}

为什么在这种情况下结果是:

CoroutineExceptionHandler got java.io.IOException

没有算术异常?

【问题讨论】:

    标签: kotlin kotlin-coroutines kotlin-android-extensions cancellation


    【解决方案1】:

    inner.join() 抛出 CancellationException,原因设置为在作业中抛出的异常。但是当CancellationException 在顶层被抛出时,CoroutineExceptionHandler 只会看到IOExceptionCancellationException 的原因)。

    【讨论】:

    • 什么是“透明且默认展开”?
    • 我认为“透明”意味着它会传播到所有作业并变成 CancellationException,而“未包装”意味着 CoroutineExceptionHandler 看到的不是 CancellationException,而是 IOException
    • 但是如果在cancel方法中指定Throwable,会不会也作为这个Job的原因?
    • 是的。他们的意思是,如果在顶层抛出 CancellationException,它最终会在 CoroutineExceptionHandler 展开。
    • 我已经对问题添加了更新,算术异常没有添加为抑制,为什么?
    猜你喜欢
    • 2023-03-03
    • 1970-01-01
    • 2019-08-23
    • 2018-05-13
    • 1970-01-01
    • 2019-12-18
    • 2019-02-19
    • 1970-01-01
    相关资源
    最近更新 更多