kotlin异常处理之----取消异常CancellationException与其他异常的区别,协程异常处理顺序

CancellationException异常是协程专门用来取消协程而使用,与其他异常在处理上是有区别的

  • 协程内部使用CancellationException来进行取消操作,这个异常会被忽略掉。
  • 当子协程取消后,不会取消父协程。(如果是其他异常,父协程也完蛋喽!)
  • 如果一个协程遇到CancellationException以外的异常,它将使用该异常来取消父协程。当父协程和子协程都结束后,异常才会被父协程处理。

下面的例子中,println("异常捕获 ${exception.message}")这句话是最后被执行的,因为上面的第三点提到,父协程处理异常是要在所有的子协程全部都执行完毕。

step1:当第二个子协程抛出异常后,向父协程抛出CancellationException来取消父协程。

step2:父协程给第一个子协程传递一个异常,第一个子协程捕获到了异常,执行finally清理资源。(这里清理资源时必须使用withContext(NonCancellable)包裹, 因为这样才不会被其他异常打扰,完成资源清理工作)

step3:当子协程都执行完成后,这里就是第一个子协程的finally执行完毕后,才使用handler处理第二个子协程抛出的异常。

@Test
fun coroutineExceptionHandlerTest2() = runBlocking<Unit> {
    var handler = CoroutineExceptionHandler{ _ , exception ->
        println("异常捕获 ${exception.message}")
    }
    var job1 = GlobalScope.launch(handler) {
        launch {
            try {
                println("第一个子协程进入")
                delay(Long.MAX_VALUE)
            } catch (e : java.lang.Exception) {
                println("第一个子协程捕获到异常,${e.message}")
            } finally {
                withContext(NonCancellable) {
                    println("第一个子协程准备清理资源")
                    delay(5000)
                    println("第一个子协程准备清理资源完毕")
                }
            }
        }
        launch {
            println("第二个子协程进入")
            delay(1000)
            throw ArithmeticException("抛出一个算数异常!!!!!!!!!")
        }
    }
    job1.join()
}
第一个子协程进入
第二个子协程进入
第一个子协程捕获到异常,Parent job is Cancelling
第一个子协程准备清理资源
第一个子协程准备清理资源完毕
异常捕获 抛出一个算数异常!!!!!!!!!

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值