在阅读了CoroutineScope的介绍和Javadoc之后,我仍然对CoroutineScope
背后的想法有些困惑。
doc的第一句话“定义新协程的范围”。我不清楚:我的协程为何需要瞄准镜?
另外,为什么不赞成使用独立的协程构建器?为什么这样做会更好:
fun CoroutineScope.produceSquares(): ReceiveChannel<Int> = produce {
for (x in 1..5) send(x * x)
}
代替
fun produceSquares(): ReceiveChannel<Int> = produce { //no longer an extension function
for (x in 1..5) send(x * x)
}
最佳答案
您仍然可以通过在GlobalScope
中生成它们来使用全局“独立”协程:
GlobalScope.launch {
println("I'm running unstructured")
}
但是,不建议这样做,因为在全局范围内创建协程与使用良好的旧线程基本上相同。您创建了它们,但是以某种方式需要跟踪引用以稍后加入/取消它们。
使用结构化并发,即将协程嵌套在它们的作用域中,您将总体上拥有一个更易于维护的系统。例如,如果在另一个内生成一个协程,则您将继承外部范围。这具有多个优点。如果取消外部协程,则取消将委派给内部协程。同样,您可以确保在所有子协程完成工作之前,外部协程不会完成。
documentation中还显示了一个很好的
CoroutineScope
示例。毕竟,显示的
produceSquares
方法的第一个版本更好,因为只有在CoroutineScope
中调用它才可以执行。这意味着您可以在其他任何协程中运行它:launch {
produceSquares()
}
在
produceSquares
内部创建的协程继承了launch
的范围。您可以确定launch
在produceSquares
之前没有完成。另外,如果您取消了launch
,这也会影响produceSquares
。此外,您仍然可以像下面这样创建全局运行的协程:
GlobalScope.produceSquares()
但是,如上所述,在大多数情况下这不是最佳选择。
我也想推广我写的一篇文章。有一些示例说明了范围的含义:https://kotlinexpertise.com/kotlin-coroutines-concurrency/