[英]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.