lag*_*ine 3 kotlin kotlin-coroutines
看来我可以使用多种机制启动协程。其中两个是coroutineScope,launch但阅读 Kotlin 协程文档时,我不清楚它们之间的区别是什么,以及何时使用其中一个而不是另一个
fun main() {
println("Main block ${Thread.currentThread().name}")
runBlocking {
coroutineScope {
println("Coroutine scope ${Thread.currentThread().name}")
}
launch {
println("Launch ${Thread.currentThread().name}")
}
}
}
Run Code Online (Sandbox Code Playgroud)
我运行了上面的代码,可以看到两者都启动了一个新的协程。有什么不同?
ACoroutineScope是一个组织性的东西 - 它允许您将协程分组在一起以强制结构化并发。基本上,它允许您控制作用域内所有内容(包括在其他协程中启动的协程)的生命周期,并处理诸如传播结果和错误以及取消作用域内所有内容之类的事情。更多信息请点击此处
所有协程构建器函数(包括launch)都在a内部CoroutineScope运行(或者作为接收器运行在a 上,如果你想这样看的话):
fun CoroutineScope.launch(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> Unit
): Job
Run Code Online (Sandbox Code Playgroud)
因此,launch示例中的调用在 current 内部运行,该 current 已由CoroutineScoperunBlocking构建器提供:
expect fun <T> runBlocking(
context: CoroutineContext = EmptyCoroutineContext,
block: suspend CoroutineScope.() -> T
): T
Run Code Online (Sandbox Code Playgroud)
看看你传递的 lambda 实际上是一个 吗CoroutineScope.() -> T?它以 aCoroutineScope作为接收器运行 - 这就是您所调用launch的。你不能从任何地方调用它!
CoroutineScope因此,当您在示例中创建 a 时,您将在所提供的内部嵌套一个。不允许其后面的其余代码继续(即它阻止执行),直到其中的所有内容都完成为止。在其中创建您自己的协程可以让您定义您可以控制的协程子集 - 您可以控制它们,但如果仍有其他协程在作用域中运行,它将继续阻塞,直到它们也完成为止。CoroutineScoperunBlockingrunBlockingCoroutineScopeCoroutineScopecancelrunBlocking
就像路易斯在另一个答案中所说的那样,您实际上并没有在您创建的范围内创建任何协程。该代码只是在runBlocking开始运行您传递的代码块的协程中运行。看一下这个:
fun main() {
println("Main")
runBlocking {
coroutineScope {
delay(1000)
println("I'm in a coroutine scope")
}
launch {
delay(500)
println("First new coroutine")
}
launch {
delay(50)
println("Second new coroutine")
}
}
}
Run Code Online (Sandbox Code Playgroud)
Main
I'm in a coroutine scope
Second new coroutine
First new coroutine
Run Code Online (Sandbox Code Playgroud)
单个协程中的代码按顺序执行 - 所以会发生什么
runBlocking块的协程CoroutineScope只影响你launch(等)在上面的东西launch并创建一个新的协程。一开始会延迟 500 毫秒,但现在它自己运行 - 不同的协程同时运行launch第二个协程。它也会自行运行,并立即延迟 50 毫秒。现在有 3 个协程在运行CoroutineScope,因此runBlocking请等待它们完成。runBlocking CoroutineScope都已完成,它可以完成并允许继续执行main()如果您launch在您创建的范围内编辑了一个协程,那么它的工作方式都是相同的 - 只是您可以对其中的内容进行细粒度的控制,并且您可以专门使用该嵌套范围内的协程,而无需影响外部范围内的事物。重要的是一旦内部作用域完成,它可以通知外部作用域一切都完成了,诸如此类的事情
| 归档时间: |
|
| 查看次数: |
1772 次 |
| 最近记录: |