我有一个父协程和子协程,如下所示:
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呢?
发布于 2021-10-20 05:19:59
withContext是一个suspend函数,而不是coroutine builder,因此没有子协程。当作业被取消时它没有停止的原因是因为它不是协作的。您需要使您的getData协同可取消。我假设它已经是一个suspend函数,如果是,那么您只需要在关键点检查正在运行该suspend函数的作业是否仍处于活动状态,并仅在活动的情况下才继续。您可以通过在suspend函数中使用coroutineContext.isActive来检查它。
临界点可能是一个循环,或者如果没有循环,但函数仍在执行一些繁重的处理,则可以将函数分成块,然后在继续处理下一个块之前,检查suspend函数的作业是否仍处于活动状态,只有在活动时才继续。
https://stackoverflow.com/questions/69639608
复制相似问题