如何在特定点暂停协程

2024-02-10

我对以下问题感到不知所措。

我有以下代码:

val parentJob: Job = Job()

launch(parent = parentJob) {
    while (true)
    {
        if (!parentJob.isCompleted)
        {
            // I want to control suspension here
            println("Resumed")
        }
    }
}

我希望能够以类似于信号量的方式控制协程何时应暂停以及何时应在代码片段的注释部分中准确恢复

我知道有suspendCancellableCoroutine但我不确定如何使用它或者它在这里是否合适

如何实现这一点或者有任何关于此的教程吗?


从回调和延续的角度来考虑协程会更有帮助,而不是线程和信号量。

在内部,当协程挂起时,整个链suspend fun调用返回一个特殊的内部对象,COROUTINE_SUSPENDED。因此,协程的整个执行只是一个函数调用,在此期间正在构建回调对象。这个回调是延续当您调用它时,执行会从返回特殊值的位置恢复COROUTINE_SUSPENDED object.

Kotlin 运行您传递给的块suspendCancellableCoroutine以延续对象作为参数。因此,您应该保存该对象并使其可供协程外部的代码使用。

这里有一些代码可能有助于您的理解。请注意,如果您想取消协程,则无需创建单独的父作业。您只需取消即可Job实例launch返回并且协程在暂停后不会恢复。

import kotlin.coroutines.*
import kotlinx.coroutines.*

var continuation: Continuation<String>? = null

fun main(args: Array<String>) {
    val job = GlobalScope.launch(Dispatchers.Unconfined) {
        while (true) {
            println(suspendHere())
        }
    }

    continuation!!.resume("Resumed first time")
    continuation!!.resume("Resumed second time")
    job.cancel()
    continuation!!.resume("This shouldn't print")
}

suspend fun suspendHere() = suspendCancellableCoroutine<String> {
    continuation = it
}

如果您仍然需要显式检查(因为执行路径上没有足够的暂停点),您可以使用isActive块可直接使用的属性:

while (isActive) ...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在特定点暂停协程 的相关文章

随机推荐