在 kotlin 协程 doc 中,它解释了“runBlocking 和 coroutineScope 之间的区别”:
我不太明白,示例代码显示
import kotlinx.coroutines.*
fun main() = runBlocking { // this: CoroutineScope
launch {
delay(200L)
println("+++Task from runBlocking")
}
coroutineScope { // Creates a coroutine scope
launch {
delay(500L)
println("+++Task from nested launch")
}
delay(100L)
println("+++ Task from coroutine scope") // This line will be printed before the nested launch
}
println("+++ Coroutine scope is over") // This line is not printed until the nested launch completes
}
日志:2019-05-16 10:47:45.107 12239-12239 +++ before enter runBlocking{}
2019-05-16 10:47:45.219 12239-12239 +++ Task from coroutine scope
2019-05-16 10:47:45.320 12239-12239 +++ Task from runBlocking
2019-05-16 10:47:45.620 12239-12239 +++ Task from nested launch
2019-05-16 10:47:45.621 12239-12239 +++ ---after exit runBlocking{}
并且 +++ Task from nested launch
按预期显示在 +++ Task from runBlocking
之后,因为它有 500L 延迟。但是如果在
launch
块之后添加一些其他的 coroutineScop{}
构建器,结果是令人困惑的。这里在
launch
之后添加了两个 coroutineScop{}
,其中有 30L 和 100L 延迟。我期待看到
30L
延迟的日志应该在 300L
内部的 coroutineScop{}
延迟日志之前显示,但它在 launch
内部完成所有 coroutineScop{}
之后显示fun testCoroutines() {
Log.e("+++", "+++ enter testCoroutines_3")
runBlocking {
launch {
println("+++ start Task from runBlocking, with 200L delay")
delay(200L)
println("+++ end Task from runBlocking, with 200L delay")
}
launch {
println("+++ start Task from runBlocking, with 50L delay")
delay(50L)
println("+++ end Task from runBlocking, with 50L delay")
}
launch {
println("+++ start Task from runBlocking, with 70L delay")
delay(70L)
println("+++ end Task from runBlocking, with 70L delay")
}
coroutineScope {
println("+++ enter Task from coroutineScope")
// Creates a coroutine scope
launch {
Log.v("+++", "+++ === start Task from nested launch, 500L")
delay(500L)
Log.v("+++", "+++ --- end Task from nested launch, 500L")
}
delay(100L)
println("+++ in Task from coroutineScope after delay(100L)")
launch {
Log.v("+++", "+++ === start Task from nested launch, 300L")
delay(300L)
Log.v("+++", "+++ --- end Task from nested launch, 300L")
}
println("+++ --- exit Task from coroutine scope") // This line will be printed before the nested launch
}
launch {
println("+++ start Task from runBlocking, with 30L delay")
delay(30L)
println("+++ end Task from runBlocking, with 30L delay")
}
launch {
println("+++ start Task from runBlocking, with 100L delay")
delay(100L)
println("+++ end Task from runBlocking, with 100L delay")
}
}
Log.e("+++", "--- exit testCoroutines_3 scope is over") // This line is not printed until the nested launch completes
}
日志:10:35:05.819 4657-4657 +++ enter testCoroutines_3
10:35:05.828 4657-4657 +++ enter Task from coroutineScope
10:35:05.833 4657-4657 +++ start Task from runBlocking, with 200L delay
10:35:05.833 4657-4657 +++ start Task from runBlocking, with 50L delay
10:35:05.833 4657-4657 +++ start Task from runBlocking, with 70L delay
10:35:05.834 4657-4657 +++ === start Task from nested launch, 500L
10:35:05.885 4657-4657 +++ end Task from runBlocking, with 50L delay
10:35:05.905 4657-4657 +++ end Task from runBlocking, with 70L delay
10:35:05.932 4657-4657 +++ in Task from coroutineScope after delay(100L)
10:35:05.933 4657-4657 +++ --- exit Task from coroutine scope
10:35:05.935 4657-4657 +++ === start Task from nested launch, 300L
10:35:06.034 4657-4657 +++ end Task from runBlocking, with 200L delay
10:35:06.235 4657-4657 +++ --- end Task from nested launch, 300L
10:35:06.334 4657-4657 +++ --- end Task from nested launch, 500L
10:35:06.335 4657-4657 +++ start Task from runBlocking, with 30L delay
10:35:06.335 4657-4657 +++ start Task from runBlocking, with 100L delay
10:35:06.366 4657-4657 +++ end Task from runBlocking, with 30L delay
10:35:06.436 4657-4657 +++ end Task from runBlocking, with 100L delay
10:35:06.437 4657-4657--- exit testCoroutines_3 scope is over
认为至少 +++ start Task from runBlocking, with 30L delay
应该在 +++ === start Task from nested launch, 500L
之后和 +++ end Task from runBlocking, with 50L delay
之前更早地出现,但它没有并且在 launch
完成所有 +++ --- end Task from nested launch, 500L
之后才出现。coroutineScope
在 coroutines 块中做了什么?(我正在测试使用 android 应用程序,单击按钮调用
testCoroutines
) 最佳答案
对于 runBlocking
和 coroutineScope
来说,在它们中启动的所有协程完成之前它们不会完成。
注意区分“直到”未完成”和“阻塞调用线程直到”。 runBlocking
是唯一一个做后者的人。
关于kotlin - 在runBlocking中使用coroutineScope有什么效果?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56171739/