android - 取消自定义 CoroutineScope

标签 android kotlin kotlin-coroutines

val scope = CoroutineScope(
        Job() + Dispatchers.Main
)
scope.launch {
    beforeExecute()
    val result = withContext(dispatcher) { doInBackground(*params) }
    if (!isCancelled) {
        postExecute(result)
    } else {
        cancelled(result)
    }
    status = Status.FINISHED
}
scope.cancel()

如果我将 scope.cancel() 放在 launch 之外,它会立即取消协程而不调用 launch block 代码。这是预期的吗?为什么会这样?应该在 launch block 结束时将 cancel 放在 launch 内如果我希望协程在启动内完成代码执行后结束?

更新

根据 Hau Luu 的回答和 Marko Topolnik 的评论,

”at the end of launch, I think the task is done and you don't need to manually cancel the Coroutine.”

“Once your task is done, the coroutine disappears from memory.”

但是在案例 2 中,如果我开始另一个启动,它将被执行,除非我们像案例 1 那样取消第一次启动中的协程。 那么是否可以确定在任务完成后协程从内存中消失而不需要我们手动调用 cancel()?Bcoz 编译器永远不会知道哪个是最后一次启动,之后它需要结束协程

案例一

scope.launch {
    Log.e("Task","1");
    scope.cancel()
}
scope.launch {
    Log.e("Task","2");
}

只打印任务 1

案例二

scope.launch {
    Log.e("Task","1");
}
scope.launch {
    Log.e("Task","2");
}

任务 1 和 2 都被打印

最佳答案

您的代码可以翻译成自然语言“在执行 scope.launch 后立即取消给定的协程”,所以我认为这是预期的行为。

对于另一个问题,我们只想在执行过程中出现错误时取消协程 - 嘿协程,在执行我给你的任务期间。如果有什么错误发生。杀了你自己。所以在启动结束时,我认为任务已经完成,你不需要手动取消协程。

更新:我写这个作为答案,因为我不能在评论中写代码。

CoroutineScope 旨在对创建/启动/容纳协程的对象的生命周期使用react。因此,当您在 CoroutineScope 上调用 cancel 方法时,您将停止一切。停止不取消。作用域创建的所有子协程,它们正在执行的所有作业,全部取消,仅此而已。工作完成了。这就是为什么您不能在 scope.cancel 之后启动另一个启动

CoroutineScope 将通过 launch 和 async 等构建器方法创建并保存对一堆 Corrountine 的引用。当你想取消一个特定的协程时。您需要取消构建器返回的作业。不取消容纳它们的范围。

https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/launch.html

val job1 = scope.launch{ print('Task 1') }
job1.cancel()
val job2 = scope.launch{ print('Task 2') }

任务 2 将正常打印。

关于android - 取消自定义 CoroutineScope,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66651468/

相关文章:

android - 有没有办法设置允许一组用户下载我的 android 应用程序的最高版本?

intellij-idea - IntelliJ Idea更改粘贴的代码

android - 与 SupervisorJob 的协程 - 取消行为

kotlin - Uncaught TypeError : this. resultContinuation_0 在 Kotlin JS 浏览器 onclick 中尝试运行挂起函数时未定义

kotlin - 如果我在 Kotlin 协程中编写阻塞代码,它仍然会阻塞线程吗?

java - 单击通知时重新启动应用程序

android - 如何更改 ListView 中的每个列表项前面

kotlin - kotlin:列出任何对象的属性-方差错误

kotlin - 从事件返回后,错误lateinit 属性适配器尚未初始化

android - 为什么 AlertDialog.Builder(Context context) 只接受 Activity 作为参数?