android - CoroutineScope 取消
问题描述
我完全了解suspendCoroutine 和suspendCancellableCoroutine 在我的示例中是如何工作的。但我想知道为什么在我调用 viewScope.cancel() 之后执行println("I finished") (第 13 行 - viewscope 块中的第二行)。我可以在此行之前使用 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
被调用,我们的协程就会进入 Canceling 状态。
取消协程代码需要协同
您需要确保您正在实施的所有协程工作都与取消合作,因此您需要定期或在开始任何长时间运行的工作之前检查取消。例如,如果您正在从磁盘读取多个文件,则在开始读取每个文件之前,请检查协程是否已取消。像这样,您可以避免在不再需要时进行 CPU 密集型工作。
来自的所有挂起函数kotlinx.coroutines
都是可取消的:withContext
等delay
。因此,如果您使用其中任何一个,则无需检查取消并停止执行或抛出CancellationException
. 但是,如果您不使用它们,请通过检查job.isActive
或ensureActive()
推荐阅读
- r - 箱线图 y 轴上的自定义刻度数
- datatable - 为什么我不能使用 gtsummary 制作表格?
- java - 使用 Gradle 创建具有多层 jar 文件的优化 docker 映像
- node.js - 如果用户 DM 机器人,discord.js 机器人会向 DM 发送垃圾邮件
- mysql - MySQL中`with xxx AS()`的等效语法是什么
- macos - 使用非 root 用户构建 docker 映像的 MacOS 卡住了
- python - 将 N 个元素的列表分组为两个或一个的子组
- kql - 一个 iff 函数可以有多个条件吗?
- reactjs - 在 ReactJs 上实时更新图像源
- python - 如何操作数据以获取熊猫数据框?