父子协程不会被取消
Parent and Child Coroutines not getting cancelled
我有一个父协程和一个子协程,如下所示:
val exceptionHandler = CoroutineExceptionHandler {_,e -> println("exception $e")}
val scope = CoroutineScope(Dispatchers.Main)
mainCoroutineJob = scope.launch(exceptionHandler){
val data = withContext(Dispatchers.IO){
val data = getData()
data
}
data?.let{
// do something with data
}
}
当我尝试使用此方法同时取消父协程和子协程时:
mainCoroutineJob.cancel("Coroutine Cancelled")
mainCoroutineJob.cancelChildren(CancellationException("Coroutine Cancelled"))
withContext里面的代码,一直在运行.
请问为什么?我们如何取消 withContext 呢?
withContext
是一个 suspend
函数,而不是 coroutine builder
,因此没有子协程。取消作业时它不停止的原因是它不合作。您需要让您的 getData
可以合作取消。我假设它已经是一个 suspend
函数,如果是这样,那么你只需要在关键点检查 运行 的作业是否 suspend
函数仍然有效,只有在它是时才继续.您可以在 suspend
函数中使用 coroutineContext.isActive
来检查它。
一个关键点可能是一个循环,或者如果没有循环但一个函数仍在做一些繁重的处理,你可以将你的函数分成块,然后在继续处理下一个块之前检查是否 suspend
函数的作业是否仍然处于活动状态,只有在活动状态下才继续。
我有一个父协程和一个子协程,如下所示:
val exceptionHandler = CoroutineExceptionHandler {_,e -> println("exception $e")}
val scope = CoroutineScope(Dispatchers.Main)
mainCoroutineJob = scope.launch(exceptionHandler){
val data = withContext(Dispatchers.IO){
val data = getData()
data
}
data?.let{
// do something with data
}
}
当我尝试使用此方法同时取消父协程和子协程时:
mainCoroutineJob.cancel("Coroutine Cancelled")
mainCoroutineJob.cancelChildren(CancellationException("Coroutine Cancelled"))
withContext里面的代码,一直在运行.
请问为什么?我们如何取消 withContext 呢?
withContext
是一个 suspend
函数,而不是 coroutine builder
,因此没有子协程。取消作业时它不停止的原因是它不合作。您需要让您的 getData
可以合作取消。我假设它已经是一个 suspend
函数,如果是这样,那么你只需要在关键点检查 运行 的作业是否 suspend
函数仍然有效,只有在它是时才继续.您可以在 suspend
函数中使用 coroutineContext.isActive
来检查它。
一个关键点可能是一个循环,或者如果没有循环但一个函数仍在做一些繁重的处理,你可以将你的函数分成块,然后在继续处理下一个块之前检查是否 suspend
函数的作业是否仍然处于活动状态,只有在活动状态下才继续。