2

我很难理解 GlobalScope 的用法和文档。文档指出:

未绑定到任何作业的全局 CoroutineScope。

全局范围用于启动在整个应用程序生命周期内运行且不会过早取消的顶级协程。全局范围的另一个用途是在 Dispatchers.Unconfined 中运行的运算符,它们没有任何与之关联的作业。

应用程序代码通常应该使用应用程序定义的 CoroutineScope。强烈建议不要在 GlobalScope 的实例上使用异步或启动。

  1. GlobalScope 不受任何工作的约束是什么意思?因为我可以

    val job = GlobalScope.launch {
        // some work
    }
    job.cancel() 
    
  2. 它说它们不会过早取消。这是什么意思?正如你在上面看到的,我可以取消它。

  3. 最后它说,它在整个应用程序生命周期中运行。因此范围一直存在,直到应用程序死亡。这与 相比如何CoroutineScopeActivity当我在 running 过程中退出 Android时CoroutineScope,它仍然会存活并运行直到完成。这是否只是意味着在CoroutineScope完成后将通过垃圾收集进行清理并且GlobalScope不会?

文档链接: https ://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-global-scope/

4

1 回答 1

3
  1. GlobalScope 不受任何工作的约束是什么意思?因为我可以做...

这是指缺少与“作用域”内的,而不是单个协程Job相关的对象。CoroutineScopeJob

  1. 它说它们不会过早取消。这是什么意思?正如你在上面看到的,我可以取消它。

在任何时候调用GlobalScope.cancel()都会抛出一个IllegalArgumentException.

所以这会产生同样的错误:

fun main(args: Array<String>) {

    val myScope : CoroutineScope = object : CoroutineScope {
        override val coroutineContext: CoroutineContext = Dispatchers.IO // no job added i.e + SupervisorJob()
    }


    val job = myScope.launch { longRunningTask() }

    Thread.sleep(5_000)
    job.cancel() // this is fine - individual coroutine cancelled
    myScope.cancel() // this will throw an error, same as GlobalScope.cancel()
    
}
  1. 最后它说,它在整个应用程序生命周期中运行。因此范围一直存在,直到应用程序死亡。这与 CoroutineScope 相比如何?当我在正在运行的 CoroutineScope 中间退出 Android Activity 时,它仍然是活动的并一直运行直到完成。这是否只是意味着 CoroutineScope 将在完成后通过垃圾收集进行清理而 GlobalScope 不会?

GlobalScope是一个对象类 - 一个单例,因此只要它运行的进程持续。 GlobalScope实现CoroutineScope它只是库附带的预定义范围。协程可以从中启动,GlobalScope但调用者必须注意保留Job对象并通过Job. 使用自定义时CoroutineScope,您可以更好地控制调用扩展函数时发生的情况CoroutineScope.cancel()——例如取消所有在该范围内“运行”的子协程。

我对这个主题没有权威,但这就是我解释文档和观察图书馆行为的方式。

老实说,我认为大多数人都难以简单明了地解释协程 - 大多数关于该主题的文章都不容易阅读,而且通常我会更加困惑。在深入研究库源代码之后,它通常会消除一些东西,但您也可以看到它仍然处于持续开发的状态。

于 2020-12-17T23:31:59.930 回答