为什么CoroutineExceptionHandler只有在coroutineContext为MainScope()时才能启动?
Why CoroutineExceptionHandler can only perform launch when the coroutineContext is 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 ...
不会打印。
为什么会这样?
显然,我们需要使用 SupervisorJob()
创建一个 Scope,这样父作业就不会受到子作业崩溃的影响。
coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
请注意 MainScope()
是 CoroutineScope(SupervisorJob() + Dispatchers.Main)
。
所述
A failure or cancellation of a child does not cause the supervisor job to fail and does not affect its other children, so a supervisor can implement a custom policy for handling failures of its children
我有下面的代码并故意触发异常被 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 ...
不会打印。
为什么会这样?
显然,我们需要使用 SupervisorJob()
创建一个 Scope,这样父作业就不会受到子作业崩溃的影响。
coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
请注意 MainScope()
是 CoroutineScope(SupervisorJob() + Dispatchers.Main)
。
A failure or cancellation of a child does not cause the supervisor job to fail and does not affect its other children, so a supervisor can implement a custom policy for handling failures of its children