如何在使用当前父级Scope的“悬浮乐趣”中启动Kotlin协程?

Rus*_*one 9 kotlin kotlinx.coroutines

如何从暂停功能启动协程并使其使用当前的示波器?(这样,直到启动的协程也结束,作用域才结束)

我想写类似下面的内容–

import kotlinx.coroutines.*

fun main() = runBlocking { // this: CoroutineScope
    go()
}

suspend fun go() {
    launch {
        println("go!")
    }
}
Run Code Online (Sandbox Code Playgroud)

但这有一个语法错误:“未解决的参考:启动”。似乎launch必须以下列方式之一运行-

GlobalScope.launch {
    println("Go!")
}
Run Code Online (Sandbox Code Playgroud)

要么

runBlocking {
    launch {
        println("Go!")
    }
}
Run Code Online (Sandbox Code Playgroud)

要么

withContext(Dispatchers.Default) {
    launch {
        println("Go!")
    }
}
Run Code Online (Sandbox Code Playgroud)

要么

coroutineScope {
    launch {
        println("Go!")
    }
}
Run Code Online (Sandbox Code Playgroud)

这些替代方法都不能满足我的需求。代码要么“阻塞”而不是“产生”,要么产生,但是父作用域在父作用域本身结束之前不会等待其完成。

我需要它在当前的父协程作用域中“生成”(启动),并且该父作用域应等待所生成的协程完成,然后结束自身。

我希望a launch内的简单内容suspend fun有效并使用其父范围。

我正在使用Kotlin 1.3cotlinx-coroutines-core:1.0.1

Rus*_*one 10

我相信我找到了一个解决方案,那就是with(CoroutineScope(coroutineContext). 下面的例子说明了这个\xe2\x80\x93

\n\n
import kotlinx.coroutines.*\n\nfun main() = runBlocking {\n    go()\n    go()\n    go()\n    println("End")\n}\n\nsuspend fun go() {\n//  GlobalScope.launch {                     // spawns, but doesn\'t use parent scope\n//  runBlocking {                            // blocks\n//  withContext(Dispatchers.Default) {       // blocks\n//  coroutineScope {                         // blocks\n    with(CoroutineScope(coroutineContext)) { // spawns and uses parent scope!\n        launch {\n            delay(2000L)\n            println("Go!")\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

然而,Rene 在上面发布了一个更好的解决方案。

\n


Ren*_*ene 6

您应该将该函数go扩展为CoroutineScope

fun main() = runBlocking {
    go()
    go()
    go()
    println("End")
}

fun CoroutineScope.go() = launch {
    println("go!")
}
Run Code Online (Sandbox Code Playgroud)

阅读本文以了解为什么在suspend不创建新协程的情况下从其他协程开始的功能不是一个好主意coroutineScope{}

约定是:如果需要启动并行协程,则在一个suspend函数中调用其他suspend函数并创建一个new CoroutineScope。结果是,协程将仅在所有新启动的协程完成后才返回(结构化并发)。

另一方面,如果您需要在不知道范围的情况下启动新协程,则可以创建的扩展功能CoroutineScope,而它本身不是suspendable。现在,调用者可以决定应使用哪个范围。