lan*_*nyf 5 kotlin kotlin-coroutines coroutinescope
在 kotlin coroutines doc 中,它解释了“runBlocking 和 coroutineScope 之间的区别”:
范围生成器
除了不同构建器提供的协程作用域之外,还可以使用 coroutineScope 构建器来声明您自己的作用域。它创建了一个协程范围,并且在所有启动的子项完成之前不会完成。
The main difference between runBlocking and coroutineScope is that the latter does not block the current thread while waiting for all children to complete.
我不太明白,示例代码显示
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
}
Run Code Online (Sandbox Code Playgroud)
日志:
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{}
Run Code Online (Sandbox Code Playgroud)
并且按预期+++ 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
}
Run Code Online (Sandbox Code Playgroud)
日志:
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
Run Code Online (Sandbox Code Playgroud)
认为至少+++ 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在协同程序块吗?
(我正在使用 android 应用程序进行测试,单击按钮即可调用testCoroutines)
这事实上coroutineScope是非阻塞并不意味着它不会等待其子协同程序到结束。
事实上,无论是runBlocking和coroutineScope将在完成之前等待每一个孩子协程到结束。
两者之间的真正区别在于他们如何等待。runBlocking阻塞当前线程,同时coroutineScope挂起当前协程。
对于两者来说都是如此runBlocking,并且coroutineScope只有在它们内启动的所有协程完成后它们才会完成。
请注意区分“直到”和“阻塞调用线程直到”。runBlocking是唯一做后者的人。
| 归档时间: |
|
| 查看次数: |
1118 次 |
| 最近记录: |