协程作用域的生命周期

问题描述 投票:0回答:1

我正在尝试更好地理解 runBlocking 和 CoroutineScope。

我写了以下代码。

serviceCall1
等是返回一些整数的挂起函数。

fun testFun1() {
        val output = compParallel(CoroutineScope(Dispatchers.IO))
        println("output is $output")
}
    
fun compParallel(scope: CoroutineScope) : Int {
        val f1 = listOf<suspend (Long) -> Int>(::serviceCall1, ::serviceCall2, ::serviceCall3, ::serviceCall4)
        return runBlocking(scope.coroutineContext) {
            launch {
                try {
                    delay(5000)
                    println("I am late")
                } catch (e: Exception) {
                    println("I am cancelled")
                } finally {
                    println("I am finalled")
                }
            }
            f1.mapIndexed {
                idx, a -> scope.async {
                    a(idx.toLong())
                }
            }.awaitAll().sum()
        }
}

当我运行它时,

I am late
I am finalled

已打印。

但是,如果我改变

        launch {
            try {
                delay(5000)
                println("I am late")
            } catch (e: Exception) {
                println("I am cancelled")
            } finally {
                println("I am finalled")
            }
        }

        scope.launch {
            try {
                delay(5000)
                println("I am late")
            } catch (e: Exception) {
                println("I am cancelled")
            } finally {
                println("I am finalled")
            }
        }

这两行不会被打印。

我的理解是,一旦

testFun1()
完成运行并且由
CoroutineScope(Dispatchers.IO)
创建的 CoroutineScope 超出范围,它将取消所有作业,因此应该打印这两行。

有人可以帮忙解释一下为什么输出是这样的吗?

kotlin-coroutines
1个回答
0
投票

在第一个场景中

I am late
I am finalled
打印

是因为

runBlocking
等待其所有子协程完成后再退出。

在第二种情况下

I am late
I am finalled
打印

是因为使用了

scope.launch
并且创建的协程不是 runBlocking 协程作用域内的协程。 runBlocking 不关心其状态并在
scope.launch
协程完成之前退出。

© www.soinside.com 2019 - 2024. All rights reserved.