gpt4 book ai didi

kotlin - 给定范围内的安全异步

转载 作者:行者123 更新时间:2023-12-01 00:27:22 24 4
gpt4 key购买 nike

我想在给定的父 CoroutineScope 中启动一个带有挂起函数的异步协程,以生成一个 Deferred,然后可以从该范围内的任何协程中使用它。

如果父级的作业被取消,我希望它的作业被取消,但如果挂起函数抛出异常,我需要在生成的 Deferred 中捕获它,而不取消父级作用域中的同级作业.

我这样做的方式很好,但我想知道是否有比这更简单、更惯用的方式:

fun <T> callIt(scope: CoroutineScope, block: suspend () -> T) : Deferred<T> {
val result = CompletableDeferred<T>()
scope.launch {
try {
result.complete(block())
} catch (e: Throwable) {
result.completeExceptionally(e)
}
}
return result
}

我喜欢处理来自挂起的 block 的异常显然是我想要的,但我不太高兴从中构建一个async启动

不起作用的东西:

  • 带有异常处理程序的异步作业。 async 捕获了它的异常,但作业仍然失败并取消了它的父作业。正如@Rene 评论的那样:async 的文档说:“它会在未能强制执行结构化并发范式时取消父作业(或外部范围)。”。

最佳答案

您可以在没有 CompletableDeferred 的情况下完成它。您需要创建一个 SupervisorJob并让 CoroutineScope 中的作业成为新作业的父级。如果作用域被取消,async-coroutine 也会被取消。但在 async 内部没有异常 - 协程将取消父作用域。

由于 Unresolved 问题 https://github.com/Kotlin/kotlinx.coroutines/issues/1578我们需要明确地完成 SupervisorJob。

fun <T> callIt(scope: CoroutineScope, block: suspend () -> T): Deferred<T> {
val supervisorJob = SupervisorJob(scope.coroutineContext[Job])
val deferred = scope.async(supervisorJob) {
block()
}
deferred.invokeOnCompletion {
supervisorJob.complete()
}
return deferred
}

关于kotlin - 给定范围内的安全异步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58229357/

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