kotlin - 为什么 CoroutineExceptionHandler 只能在 coroutineContext 为 MainScope() 时执行启动?
问题描述
我有下面的代码并故意触发一个异常被捕获errorHandler
private var coroutineScope: CoroutineScope? = null
private val mainThreadSurrogate = newSingleThreadContext("Test Main")
@Before
fun setUp() {
Dispatchers.setMain(mainThreadSurrogate)
}
@After
fun tearDown() {
// reset main dispatcher to the original Main dispatcher
Dispatchers.resetMain()
mainThreadSurrogate.close()
}
private val errorHandler = CoroutineExceptionHandler { context, error ->
println("Launch Exception ${Thread.currentThread()}")
coroutineScope?.launch(Dispatchers.Main) {
println("Launch Exception Result ${Thread.currentThread()}")
}
}
@Test
fun testData() {
runBlocking {
coroutineScope = MainScope()
coroutineScope?.launch(errorHandler) {
println("Launch Fetch Started ${Thread.currentThread()}")
throw IllegalStateException("error")
}?.join()
}
}
这将导致
Launch Fetch Started Thread[Test Main @coroutine#2,5,main]
Launch Exception Thread[Test Main @coroutine#2,5,main]
Launch Exception Result Thread[Test Main @coroutine#3,5,main]
如果我更改coroutineScope = MainScope()
为
coroutineScope = CoroutineScope(Dispatchers.Main)
coroutineScope = CoroutineScope(Dispatchers.IO)
coroutineScope?.launch(Dispatchers.Main) {...}
不会运行,即不会Launch Exception Result ...
打印。
为什么会这样?
解决方案
显然,我们需要使用 来创建一个 Scope SupervisorJob()
,这样父作业就不会受到子作业崩溃的影响。
coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
注意MainScope()
是CoroutineScope(SupervisorJob() + Dispatchers.Main)
。
如中所述SupervisorJob
一个孩子的失败或取消不会导致主管工作失败,也不会影响其其他孩子,因此主管可以实施自定义策略来处理其孩子的失败
推荐阅读
- android - 当从画廊或相机选项中选择选项时获取错误
- javascript - 如何从函数返回文本?
- templates - 更新到 Helix Ultimate 2.x 不起作用 -> HTML 错误 500
- linux - 如何从 /proc/schedstat 获取增量百分比
- asp.net-core - .Net Core 将数据从 Excel 导入数据库时如何自动生成 ID?
- pine-script - 如何在tradingview pinescript中的最新/实时蜡烛之前对历史蜡烛的高点进行编码/超过/吞没/打破?
- c++ - 具有特殊情况的 C++ 动态返回类型
- css - 组元素的转换转换属性在 Firefox 中不起作用
- typescript - react-native useRoute hook:“对象”类型上不存在属性“.....”
- java - javax.persistence.PersistenceException:org.hibernate.HibernateException:HHH000142:字节码增强失败:echosign.agreement.Participation