请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

uncaughtExceptionHandler让协程抛出异常?

类 StandardCoroutine 中的 it.uncaughtExceptionHandler.uncaughtException(it, e) 到底是什么意思?在网上也没搜到啥靠谱的答案。

为啥他会令resumeWithException 后协程抛出异常崩溃掉?

class StandardCoroutine(context: CoroutineContext) : AbstractCoroutine<Unit>(context) {
    override fun handleJobException(e: Throwable): Boolean {
        context[CoroutineExceptionHandler]?.handleException(context, e) ?:
                Thread.currentThread().let {
                    it.uncaughtExceptionHandler.uncaughtException(it, e)
                }
        return true
    }
}

这是简单的测试代码

suspend fun main(){
    log(1)
    val job = GlobalScope.launch{
        log(2)
        val s: String  = demo2()
        log(s)
    }
    job.join()
    log(5)
}

suspend fun demo2() = suspendCoroutine<String> { c ->
    thread{
        Thread.sleep(1000)
        c.resumeWithException(Exception("test 500"))
    }
}

上面的例子中如果注释掉 it.uncaughtExceptionHandler.uncaughtException(it, e),那么就不会抛出异常。反之就抛异常。

而根据分析BaseContinuationImpl=>resumeWith函数,分析可知 resumeWithException 操作并不会导致抛异常。

 


正在回答

1回答

CoroutineLite也有对应的实现,其实就是先判断当前作用域内有没有一场处理器,如果没有,就调用所在线程的异常处理器,线程默认的异常处理器被调用了就是这个结果。

可以去看下CoroutineLite的异常处理实现。

0 回复 有任何疑惑可以回复我~
  • 提问者 慕前端9039556 #1
    那到底是不是他给我抛出的异常。泪目了
    回复 有任何疑惑可以回复我~ 2020-11-13 16:57:57
  • 提问者 慕前端9039556 #2
    我就纳了闷儿了,协程源码里拐弯抹角的把异常隐晦的转为 Result类型作为值来传递。为啥 launch里面反而又把异常给throw出来,降低程序的安全性呢。。
    回复 有任何疑惑可以回复我~ 2020-11-13 17:20:53
  • bennyhuo 回复 提问者 慕前端9039556 #3
    其实并没有,跟线程的逻辑一样,异常不处理就是该崩溃,没什么好说的。包装成result传递是为了把异步的异常传递给挂起点恢复的位置。
    回复 有任何疑惑可以回复我~ 2020-11-16 09:27:18
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信