在阅读了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的范围。您可以确定launchproduceSquares之前没有完成。另外,如果您取消了launch,这也会影响produceSquares

此外,您仍然可以像下面这样创建全局运行的协程:
GlobalScope.produceSquares()

但是,如上所述,在大多数情况下这不是最佳选择。

我也想推广我写的一篇文章。有一些示例说明了范围的含义:https://kotlinexpertise.com/kotlin-coroutines-concurrency/

10-07 13:53