简体   繁体   English

Kotlin:调用 CoroutineScope.launch 与在协程内启动之间的区别

[英]Kotlin: Difference between calling CoroutineScope.launch vs launch inside a coroutine

I am trying to understand structured concurrency in Kotlin and I am unable to wrap my head across this piece of code.我试图理解 Kotlin 中的结构化并发,但我无法理解这段代码。

fun main(): Unit = runBlocking {
    other(this)
}

suspend fun other(scope: CoroutineScope) {
    val job = scope.launch {
        scope.launch {
            delay(200)
            println("e")
        }
        println("a")
    }
    job.invokeOnCompletion {
        println("Complete")
    }
}

The code prints代码打印

a
Complete
e

While if I replace the inner scope.launch call with launch , like this而如果我用launch替换内部scope.launch调用,就像这样

suspend fun other(scope: CoroutineScope) {
    val job = scope.launch {
       launch {
            delay(200)
            println("e")
        }
        println("a")
    }
    job.invokeOnCompletion {
        println("Complete")
    }
}

It prints它打印

a
e
Complete

This shows that the first example does not follow structured concurrency since parent job finished before child job.这表明第一个示例不遵循结构化并发,因为父作业在子作业之前完成。 My confusion is, why does this happen?我的困惑是,为什么会这样?

I felt that scope.launch maybe equivalent to calling launch (which should be equivalent to this.launch and this refers to scope ) in this case.在这种情况下,我觉得scope.launch可能等同于调用launch (应该等同于this.launch并且 this 指的是scope )。 But seems like this is not true.但似乎这不是真的。 Can someone explains why the first one results in unstructured concurrency and what is the difference between the two launch calls?有人可以解释为什么第一个会导致非结构化并发吗?这两个启动调用之间有什么区别? Thanks!谢谢!

In the first code, while the inner launch looks like it's a child of the outer launch, it's actually not -- it's a sibling of the outer launch since they were both launched from the same scope. So waiting for the outer launch's job to complete doesn't wait for the inner one.在第一个代码中,虽然内部启动看起来像是外部启动的子项,但实际上不是——它是外部启动的兄弟,因为它们都是从同一个 scope 启动的。所以等待外部启动的工作完成不等待内心的。

The second code uses structured concurrency since the inner launch uses the scope created by the outer launch (the receiver of the launch block).第二个代码使用结构化并发,因为内部启动使用外部启动(启动块的接收者)创建的 scope。 In this case it's a child of the outer launch so waiting for the outer job to complete waits for the child to complete as well.在这种情况下,它是外部启动的子项,因此等待外部作业完成也会等待子项完成。

The second one is what you're supposed to do: use the CoroutineScope receiver of the launch block to launch child jobs.第二个是您应该做的:使用启动块的 CoroutineScope 接收器启动子作业。 Using some other scope instead does not provide structured concurrency.使用其他一些 scope 不提供结构化并发。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用 GlobalScope.launch 和 CoroutineScope().launch 启动协程有区别吗? - Is there a difference between using GlobalScope.launch and CoroutineScope().launch to launch a coroutine? 为什么CoroutineScope.launch和Coroutine.async是扩展函数而不是CoroutineScope的成员函数? - Why is CoroutineScope.launch and Coroutine.async are extension functions instead of a member function of CoroutineScope? 调用 CoroutineScope.launch 时,Dispatchers.Default 是如何转换为 CoroutineContext 的? - When calling CoroutineScope.launch, how is Dispatchers.Default converted to a CoroutineContext? 对于 Kotlin Coroutine,使用 CoroutineScope 启动时,parentJob 放在哪里? - For Kotlin Coroutine, where to put parentJob, when using CoroutineScope to launch? Kotlin 协程启动{} vs 启动{ withContext{} } - Kotlin Coroutine launch{} vs launch{ withContext{} } 如何对调用 CoroutineScope.launch 的 function 进行单元测试 - how to unit test a function which called CoroutineScope.launch Kotlin 中 CoroutineScope 和 coroutineScope 的区别 - Difference between CoroutineScope and coroutineScope in Kotlin kotlin 中两个协程启动的区别 - Differences between two coroutine launch in kotlin Kotlin Coroutine Launch 在另一个启动中被顺序调用 - Kotlin Coroutine Launch inside another launch getting called sequentially kotlin 协程多重启动 - kotlin Coroutine multiple launch
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM