我正在尝试更好地理解 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 超出范围,它将取消所有作业,因此应该打印这两行。
有人可以帮忙解释一下为什么输出是这样的吗?
在第一个场景中
I am late
I am finalled
打印 是因为
runBlocking
等待其所有子协程完成后再退出。
在第二种情况下
I am late
I am finalled
打印 是因为使用了
scope.launch
并且创建的协程不是 runBlocking 协程作用域内的协程。 runBlocking 不关心其状态并在 scope.launch
协程完成之前退出。