在suspendCoroutine中用throw代替resumeWithException

举个例子

suspend fun foo() {
    try {
        suspendCoroutine { cont -> throw Error() }
    } catch (ex: Throwable) {
        println("catch")
    }
    println("done")
}

这样throw其实和cont.resumeWithException(Error()) 效果一样,会打印”catch”和”done”。
不过如果是这样

suspend fun foo() {
    try {
        suspendCoroutine { cont -> 
            thread(name = "thread-0") { throw Error() }
        }
    } catch (ex: Throwable) {
        println("catch")
    }
    println("done")
}

  这样只会打印出thread-0上的Exception信息。
  原因很简单,异常是在thread-0上抛出的,而不resume/resumeWithException 的话,这个协程就永远都不会继续执行了
  这种情况其实应该用

cont.resumeWithException(Error())

来代替throw。
不过能不能还用throw呢?当然可以,很简单,那就这样

thread(name = "thread-0") {
    Thread.currentThread().setUncaughtExceptionHandler { _, ex -> 
        cont.resumeWithException(ex)
    }
    throw Error()
}

实际中一般是遇到这样的场景

suspendCoroutine { cont->
    threadPool.submit {
        try {
            val result = blockOperation() // may throw exception
            cont.resume(result)
        } catch (ex: Throwable) {
            cont.resumeWithException(ex)
        }
    }
}

改造下

fun <T> ExcecutorService.submitWithContinuatioin(cont: Continuation<*>, Callable<T> task) {
    this.submit {
        Thread.currentThread().setUncaughtExceptionHandler { _, e -> cont.resumeWithException(e) }
        task.call()
    }
}

suspendCoroutine { cont ->
    threadPool.submitWithContinuation(cont) {
        cont.resume(blockOperation())
    }
}

不用每次都要写try…catch啦

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值