簡體   English   中英

Kotlin:調用 CoroutineScope.launch 與在協程內啟動之間的區別

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

我試圖理解 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")
    }
}

代碼打印

a
Complete
e

而如果我用launch替換內部scope.launch調用,就像這樣

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

它打印

a
e
Complete

這表明第一個示例不遵循結構化並發,因為父作業在子作業之前完成。 我的困惑是,為什么會這樣?

在這種情況下,我覺得scope.launch可能等同於調用launch (應該等同於this.launch並且 this 指的是scope )。 但似乎這不是真的。 有人可以解釋為什么第一個會導致非結構化並發嗎?這兩個啟動調用之間有什么區別? 謝謝!

在第一個代碼中,雖然內部啟動看起來像是外部啟動的子項,但實際上不是——它是外部啟動的兄弟,因為它們都是從同一個 scope 啟動的。所以等待外部啟動的工作完成不等待內心的。

第二個代碼使用結構化並發,因為內部啟動使用外部啟動(啟動塊的接收者)創建的 scope。 在這種情況下,它是外部啟動的子項,因此等待外部作業完成也會等待子項完成。

第二個是您應該做的:使用啟動塊的 CoroutineScope 接收器啟動子作業。 使用其他一些 scope 不提供結構化並發。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM