Jos*_*ose 8 kotlin kotlin-coroutines
谁能解释他们之间的区别?我认为范围提供了一个引用(例如Job)来取消它们,上下文提供了对底层线程的引用。是这样吗?
Wil*_*zel 26
是的,原则上你是对的,这里有更多细节。
范围
viewModelScope
在 Android 中)以避免泄漏的方法语境
上下文决定协程将在哪个线程上运行。有四个选项:
Dispatchers.Default
- 用于 CPU 密集型工作(例如对大列表进行排序)Dispatchers.Main
- 这将取决于您添加到程序运行时依赖项中的内容(例如kotlinx-coroutines-android
,对于 Android 中的 UI 线程)Dispatchers.Unconfined
- 在没有特定线程的情况下运行无限制的协程Dispatchers.IO
- 用于繁重的 IO 工作(例如长时间运行的数据库查询)以下示例将范围和上下文结合在一起。它创建了一个新的作用域,在该作用域中,协程将在指定用于 IO 工作的线程上运行(如果未更改),并通过其作用域取消它们。
val scope = CoroutineScope(context = Dispatchers.IO)
val job = scope.launch {
val result = suspendFunc1()
suspendFunc2(result)
}
// ...
scope.cancel() // suspendFunc1() and suspendFunc2() will be cancelled
Run Code Online (Sandbox Code Playgroud)
s1m*_*nw1 11
CoroutineScope
有-a CoroutineContext
。
例如,如果您有:
runBlocking { // defines coroutineScope
launch(Dispatchers.Default) { //inherits coroutineScope but changes context
}
}
Run Code Online (Sandbox Code Playgroud)
runBlocking
定义一个CoroutineScope
(在这里了解它)launch
继承。通过在此处显式指定调度程序来覆盖上下文。如果您查看 的定义launch
,您会发现它带有一个可选的CoroutineContext
:
public fun CoroutineScope.launch(
context: CoroutineContext = EmptyCoroutineContext,
...
)
Run Code Online (Sandbox Code Playgroud)
上下文的另一部分是协程的名称:
launch(CoroutineName("launchMe") + Dispatchers.Default) {
println("")
}
Run Code Online (Sandbox Code Playgroud)
它们确实紧密相关。您可能会说,这可以CoroutineScope
正式定义CoroutineContext
继承的方式。
CoroutineScope
本身没有数据,它只保存一个CoroutineContext
。它的关键作用是作为传递给的块的隐式接收者launch
,async
等等。
请参阅以下示例:
runBlocking {
val scope0 = this
// scope0 is the top-level coroutine scope.
scope0.launch {
val scope1 = this
// scope1 inherits its context from scope0. It replaces the Job field
// with its own job, which is a child of the job in scope0.
// It retains the Dispatcher field so the launched coroutine uses
// the dispatcher created by runBlocking.
scope1.launch {
val scope2 = this
// scope2 inherits from scope1
}
}
}
Run Code Online (Sandbox Code Playgroud)
您可以看到如何CoroutineScope
协调协程上下文的继承。如果您在中取消作业scope1
,这将传播到,scope2
同时也将取消launch
ed作业。
请注意关键的语法功能:我显式编写了代码scope0.launch
,但是如果我只是编写了代码launch
,则意味着完全相同。这就是CoroutineScope
帮助“自动”传播范围的方式。
归档时间: |
|
查看次数: |
2038 次 |
最近记录: |