android - CoroutineScope 取消

标签 android kotlin coroutine

我完全理解 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 中的所有挂起函数都是可取消的:withContextdelay 等。因此,如果您正在使用它们中的任何一个,则无需' 需要检查取消并停止执行或抛出 CancellationException。但是,如果您不使用它们,请通过检查 job.isActiveensureActive()

让您的协程代码协作

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

相关文章:

java - java.lang.IllegalArgumentException 导致指定为非 null 的参数为 null

java - NetSuite 的 OAuth 1.0 身份验证

java - 在 kotlin 中沟通父类及其内部类的最佳方式是什么?

c++ - Lua协程

Python - 如何使用 asyncio 同时运行多个协程?

android - 我应该使用什么库进行 base64 编码/解码

android - android makefile 中的额外信息

android - 网站上的链接可以使用 token 登录应用程序或回退到网站

android - registerForActivityResult 可以在协程中使用吗?

java - 如何将位图附加到电子邮件android