协程作用域取消

Gök*_*ğcı 2 android coroutine kotlin

我完全理解 suspendCoroutine 与 suspendCancellableCoroutine 在我的示例中是如何工作的。但我想知道为什么println("I finish") (第 13 行 - viewscope 块中的第二行)在我调用 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 :)")
}
Run Code Online (Sandbox Code Playgroud)

iam*_*sal 5

如果我们只是调用cancel,\xe2\x80\x99 并不意味着协程工作将停止。如果您正在执行一些相对繁重的计算,例如从多个文件中读取,则没有任何东西可以自动阻止您的代码运行。一旦job.cancel被调用,我们的协程就会进入取消状态。

\n

取消协程代码需要配合

\n

您需要确保您执行的所有协程工作\xe2\x80\x99 都与取消配合,因此您需要定期或在开始任何长时间运行的工作之前检查取消情况。例如,如果您\xe2\x80\x99正在从磁盘读取多个文件,那么在开始读取每个文件之前,请检查协程是否被取消。这样,当不再需要它\xe2\x80\x99s 时,你可以避免执行CPU 密集型工作。

\n

所有挂起函数kotlinx.coroutines都是可取消的:withContextdelay。因此,如果您\xe2\x80\x99 正在使用其中任何函数,则\xe2\x80\x99 不需要检查取消并停止执行或抛出CancellationException. 但是,如果您\xe2\x80\x99不使用它们,请通过检查job.isActive或使您的协程代码合作ensureActive()

\n