我正在阅读 Coroutine Basics试图理解和学习它。
这里有一段代码:
fun main() = runBlocking { // this: CoroutineScope
launch {
delay(200L)
println("Task from runBlocking")
}
coroutineScope { // Creates a new coroutine scope
launch {
delay(900L)
println("Task from nested launch")
}
delay(100L)
println("Task from coroutine scope") // This line will be printed before nested launch
}
println("Coroutine scope is over") // This line is not printed until nested launch completes
}
输出如下:
Task from coroutine scope
Task from runBlocking
Task from nested launch
Coroutine scope is over
我的问题是为什么这行:
println("Coroutine scope is over") // This line is not printed until nested launch completes
总是最后调用?
不应该调用它,因为:
coroutineScope { // Creates a new coroutine scope
....
}
被暂停了?
那里还有一个注释:
The main difference between runBlocking and coroutineScope is that the latter does not block the current thread while waiting for all children to complete.
我不明白 coroutineScope 和 runBlocking 在这里有何不同? coroutineScope 看起来像它的阻塞,因为它只在完成后才到达最后一行。
有人能告诉我吗?
提前致谢。
最佳答案
I don't understand how coroutineScope and runBlocking are different here? coroutineScope looks like its blocking since it only gets to the last line when it is done.
有两个独立的世界:可暂停世界(在协程内)和不可暂停世界。一旦你进入 runBlocking
的主体,你就进入了可暂停的世界,suspend fun
的行为就像阻塞代码一样,直到你无法进入下一行suspend fun
返回。 coroutineScope
是一个 suspend fun
,仅当其中的所有协程完成时才返回。因此最后一行必须打印在最后。
我从似乎受到读者点击的评论中复制了上述解释。这是原始答案:
从block中的代码来看,你的理解是正确的。 runBlocking
和 coroutineScope
的区别发生在较低的层次:当协程被阻塞时线程发生了什么?
runBlocking
不是 suspend fun
。调用它的线程会一直留在其中,直到协程完成。
coroutineScope
是一个暂停乐趣
。如果你的协程挂起,coroutineScope
函数也会被挂起。这允许顶层函数,一个创建协程的非挂起函数,继续在同一个线程上执行。线程已经“转义”了 coroutineScope
block 并准备好做一些其他工作。
在您的具体示例中:当您的 coroutineScope
暂停时,控制权返回到 runBlocking
内的实现代码。这段代码是一个事件循环,它驱动你在其中启动的所有协程。在您的情况下,将有一些协程计划在延迟后运行。时间到了会恢复相应的协程,运行一小会儿,挂起,然后控制又回到runBlocking
里面。
虽然上面描述了概念上的相似之处,但它也应该向您展示 runBlocking
是一个与 coroutineScope
完全不同的工具。
runBlocking
是一个低级结构,仅用于框架代码或像您这样的自包含示例。它将现有线程转换为事件循环,并使用 Dispatcher
创建其协程,将恢复的协程发布到事件循环的队列中。
coroutineScope
是一个面向用户的构造,用于描绘在其中被并行分解的任务的边界。您可以使用它方便地等待其中发生的所有 async
工作,获得最终结果,并在一个中心位置处理所有故障。
https://stackoverflow.com/questions/53535977/