在runBlocking中使用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
}

日志:

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{}之后添加一些其他构建器,则结果令人困惑。

这里launchcoroutineScop{}延迟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协同程序中的功能是什么?

(我正在使用android应用程序进行测试,只需点击一下按钮即可调用testCoroutines

马克·托波尼克(Marko Topolnik)

两者都是对的,runBlocking并且coroutineScope直到它们中所有的协程都完成后它们才完成。

注意将“直到完成”和“直到阻塞调用线程”区分开。runBlocking是唯一做后者的人。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何使用runBlocking等待CoroutineScope完成

koltin,与直接使用CoroutineScope和从CoroutineScope派生类有什么不同

协程:runBlocking vs coroutineScope

在Kotlin中使用runBlocking之后,为什么仍需要添加job.join()?

numpy vander 函数有什么作用,为什么在回归中使用它?

在Haskell中使用“严格通配符”何时有用,它有什么作用?

定位JavaScript时在Kotlin协程中使用runBlocking?

在协程中使用runBlocking会发生不好的事情吗?

在OpenCV中使用GaussianBlur函数的减法_gaussian_blur函数有什么作用?

$'text'在Bash中到底有什么作用?可以在Zsh中使用吗?

在 Coq 中使用展开策略然后折叠有什么作用吗?

在TransactionScope中,调用ToList()以便稍后在事务中使用的变量有什么作用?

kotlin coroutines,coroutineScope和withContext有什么区别

为什么Node.js的Assert.js在其代码中使用!!! value?它有什么作用?

当在带有括号的连接 SELECT 语句中使用“TOTAL ON”时,实际上有什么作用?

在Postgres中使用jsonb(与Django的JSONField一起使用)时,唯一索引实际上有什么作用?

纸浆:lpDot()有什么作用,如何使用

使用git checkout命令有什么作用?

为什么使用5.005;有副作用?

在UNIX命令前使用#有什么作用?

在Python的for循环中使用range(len(x))时添加索引有什么作用?例如范围(len(x [0])

为什么在带有ajax更新面板的用户控件中使用文件上传功能不起作用?

我在网格中使用数字文本框。但是数据没有绑定。为什么它不起作用?

在带有Bootstrap的Rails 6中使用webpacker时,为什么我的js.erb视图不起作用?

在 MaterialButton 中使用 materialTapTargetSize 有什么不同

在DRF中使用HyperlinkedModelSerializer有什么好处?

在devDependencies中使用npm有什么影响?

在rails中使用unscope有什么意义

在Java中使用Upcasting有什么需要?