Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 在runBlocking中使用coroutineScope有什么效果?_Kotlin_Kotlin Coroutines_Coroutinescope - Fatal编程技术网

Kotlin 在runBlocking中使用coroutineScope有什么效果?

Kotlin 在runBlocking中使用coroutineScope有什么效果?,kotlin,kotlin-coroutines,coroutinescope,Kotlin,Kotlin Coroutines,Coroutinescope,在kotlin协程中,它解释了“runBlocking和coroutineScope之间的区别”: 范围生成器 除了不同构建器提供的协同程序作用域之外,还可以使用协同程序作用域构建器声明自己的作用域。它创建了一个协同程序作用域,直到所有启动的子项完成后才完成runBlocking和coroutineScope之间的主要区别在于后者在等待所有子线程完成时不会阻塞当前线程 我不太明白,示例代码显示 import kotlinx.coroutines.* fun main() = runBlocki

在kotlin协程中,它解释了“runBlocking和coroutineScope之间的区别”:

范围生成器

除了不同构建器提供的协同程序作用域之外,还可以使用协同程序作用域构建器声明自己的作用域。它创建了一个协同程序作用域,直到所有启动的子项完成后才完成
runBlocking和coroutineScope之间的主要区别在于后者在等待所有子线程完成时不会阻塞当前线程

我不太明白,示例代码显示

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{}
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
嵌套启动的
+++任务
按预期显示在运行阻塞的
+++任务之后,因为它有500L延迟

但是如果在
coroutineScop{}
块之后添加一些其他
launch
构建器,结果会令人困惑

这里在
coroutineScop{}
之后添加了两个
launch
,其中有30L和100L延迟

我本来希望看到
30L
延迟的日志应该在
coroutineScop{}
中的
300L
延迟日志之前显示,但是它在
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

}
日志:

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{}
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
认为至少运行阻塞的
+++启动任务(延迟30L
)应在
++++==嵌套启动的启动任务(延迟500L
)之后和运行阻塞的
+++结束任务(延迟50L
)之前提前显示,但是它没有,并且在所有
launch
都在
++---从嵌套启动结束任务500L
完成后显示

coroutineScope
在coroutines块中做什么


(我正在使用android应用程序进行测试,通过点击按钮调用
testCoroutines

对于
runBlocking
coroutineScope
来说,只有在它们内部启动的所有coroutines完成后,它们才会完成


注意区分“直到”和“直到”阻塞调用线程
runBlocking
是唯一一个执行后者的方法。

事实上,
coroutineScope
是非阻塞的,并不意味着它不等待其子coroutines完成

事实上,
runBlocking
coroutineScope
都将等待每个子coroutine完成后再完成

两者之间的真正区别在于他们等待的方式
runBlocking
阻塞当前线程,而
coroutineScope
挂起当前的coroutine。

这也有帮助


quote:“查看fetchDocs的执行方式,您可以看到挂起是如何工作的。每当挂起协同程序时,当前堆栈帧(Kotlin用来跟踪哪个函数正在运行及其变量的位置)复制并保存为以后。当它恢复时,堆栈帧被复制回保存的地方,并再次运行。在动画的中间。 — 当主线程上的所有协同程序都挂起时,主线程可以自由地更新屏幕和处理用户事件。同时,挂起并恢复替换回调。“

谢谢!因此,我们可以考虑<代码> CordOutEngult< /C> >与<代码> RunCudio(排序)一样,它也将<代码> Bug < /Cord>执行,以便直到其所有代码>启动/代码>完成后,在<代码> COROTENEVER 块之后的代码将不被执行。(即使它里面的
launch
在不同的线程中?你应该避免使用
block
这个术语来表示除阻塞Java线程之外的任何其他内容,这样做时总是会引起混淆。
runBlocking
coroutineScope
有着非常不同的用途,它们之间没有重叠,而且都是相同的。)顺便说一句,所有的协同程序(最上面的和在其中启动的)可能共享同一个线程,这对行为没有影响。