作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在玩协程,发现了一些非常奇怪的行为。我想使用 suspendCoroutine()
在我的项目中转换一些异步请求.这是显示此问题的一段代码。
在第一种情况下,当在 runBlocking
中调用挂起函数时协程,来自 continuation 的异常进入 catch 块,然后 runBlocking
成功完成。但在第二种情况下,当创建新 async
时协程,异常通过 catch 块并使整个程序崩溃。
package com.example.lib
import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine
object Test {
fun runSuccessfulCoroutine() {
runBlocking {
try {
Repository.fail()
} catch (ex: Throwable) {
println("Catching ex in runSuccessfulCoroutine(): $ex")
}
}
}
fun runFailingCoroutine() {
runBlocking {
try {
async { Repository.fail() }.await()
} catch (ex: Throwable) {
println("Catching ex in runFailingCoroutine(): $ex")
}
}
}
}
object Repository {
suspend fun fail(): Int = suspendCoroutine { cont ->
cont.resumeWithException(RuntimeException("Exception at ${Thread.currentThread().name}"))
}
}
fun main() {
Test.runSuccessfulCoroutine()
println()
Test.runFailingCoroutine()
println("We will never get here")
}
Catching ex in runSuccessfulCoroutine(): java.lang.RuntimeException: Exception at main
Catching ex in runFailingCoroutine(): java.lang.RuntimeException: Exception at main
Exception in thread "main" java.lang.RuntimeException: Exception at main
at com.example.lib.Repository.fail(MyClass.kt:32)
at com.example.lib.Test$runFailingCoroutine$1$1.invokeSuspend(MyClass.kt:22)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:32)
at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:236)
at kotlinx.coroutines.EventLoopBase.processNextEvent(EventLoop.kt:123)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:69)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:45)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:35)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
at com.example.lib.Test.runFailingCoroutine(MyClass.kt:20)
at com.example.lib.MyClassKt.main(MyClass.kt:41)
at com.example.lib.MyClassKt.main(MyClass.kt)
Process finished with exit code 1
coroutineScope { ... }
将缓解
runFailingCoroutine()
中的问题
fun runFailingCoroutine() = runBlocking {
try {
coroutineScope { async { fail() }.await() }
} catch (ex: Throwable) {
println("Catching ex in runFailingCoroutine(): $ex")
}
}
最佳答案
你的第二个例子的行为是正确的,这是结构化并发的工作。
因为内部async
块抛出异常,这个协程被取消。由于结构化并发,父作业也被取消。
看这个小例子:
val result = coroutineScope {
async {
throw IllegalStateException()
}
10
}
async
结果。内部协程被取消,外部作用域也被取消。
supervisorScope
.在这种情况下,内部协程可能会失败而不会使外部协程失败。
val result = supervisorScope {
async {
throw IllegalStateException()
}
10
}
关于exception - Kotlin 协程无法处理异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53238495/
在我的设置中,我试图有一个界面 Table继承自 Map (因为它主要用作 map 的包装器)。两个类继承自 Table - 本地和全局。全局的将有一个可变的映射,而本地的将有一个只有本地条目的映射。
Rust Nomicon 有 an entire section on variance除了关于 Box 的这一小节,我或多或少地理解了这一点和 Vec在 T 上(共同)变体. Box and Vec
我是一名优秀的程序员,十分优秀!