我完全理解 suspendCoroutine 与 suspendCancellableCoroutine 在我的示例中的工作方式。但我想知道为什么 println("I finished") (第 13 行 - viewscope block 中的第二行) 在我调用 viewScope.cancel() 之后执行。我可以在这一行之前用 isActive 标志修复它,但我不想检查每一行。我在那里错过了什么。我如何取消范围?谢谢
import kotlinx.coroutines.*
import java.lang.Exception
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
fun main() {
val parentJob = Job()
val viewScope = CoroutineScope(Dispatchers.IO + parentJob)
viewScope.launch {
println(tryMe())
println("I finished")
}
Thread.sleep(2000)
viewScope.cancel()
Thread.sleep(10000)
}
suspend fun tryMe() = suspendCoroutine<String> {
println("I started working")
Thread.sleep(6000)
println("Im still working :O")
it.resume("I returned object at the end :)")
}
suspend fun tryMe2() = suspendCancellableCoroutine<String> {
println("I started working")
Thread.sleep(6000)
println("Im still working :O")
it.resume("I returned object at the end :)")
}
suspend fun tryMe3() = suspendCancellableCoroutine<String> {
it.invokeOnCancellation { println("I canceled did you heard that ?") }
println("I started working")
Thread.sleep(6000)
if (it.isActive)
println("Im still working :O")
it.resume("I returned object at the end :)")
}
最佳答案
如果我们只是调用cancel
,并不意味着协程的工作会停止。如果你正在执行一些相对繁重的计算,比如从多个文件中读取,没有什么可以自动停止你的代码运行。一旦 job.cancel
被调用,我们的协程就会进入 Cancelling 状态。
取消协程代码需要配合
您需要确保您正在实现的所有协程工作都与取消协作,因此您需要定期或在开始任何长时间运行的工作之前检查取消。例如,如果您正在从磁盘读取多个文件,那么在开始读取每个文件之前,请检查协程是否已取消。这样,您就可以避免在不再需要时执行 CPU 密集型工作。
kotlinx.coroutines
中的所有挂起函数都是可取消的:withContext
、delay
等。因此,如果您正在使用它们中的任何一个,则无需' 需要检查取消并停止执行或抛出 CancellationException
。但是,如果您不使用它们,请通过检查 job.isActive
或 ensureActive()
关于android - CoroutineScope 取消,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65239627/