父子协程不会被取消

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 函数的作业是否仍然处于活动状态,只有在活动状态下才继续。