我有一个父级协程和子级协程,像这样:
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
函数的任务是否仍然处于活动状态,只有当它处于活动状态时才继续。