在 Kotlin 中组合协程上下文的目的是什么?

Jae*_*ung 5 android kotlin kotlin-android-extensions kotlin-coroutines

https://kotlinlang.org/docs/reference/coroutines/coroutine-context-and-dispatchers.html#combining-context-elements

官方文档说我可以结合一些协程上下文,但是这样做的目的是什么,效果是什么?这是否意味着协程的生命周期仅限于两种上下文?

fer*_*ini 7

我认为你很困惑CoroutineContext并且CoroutineDispatcher(可能也是CoroutineScope)。Dispatcher只是一种Context。其他人可以是例如。Job, CoroutineName, CoroutineExceptionHandler. 您可以组合多个这些 - 例如。设置调度程序和错误处理程序 - 但每种类型只有一个。

组合多个调度器没有意义,只会应用最后一个。

我找到了 Coroutines 的讨论!需要把他们全都抓到!来自 KotlinConf 2019的 Florina Muntenescu 和 Manuel Vivo很好地解释了其中的一些。


Mar*_*nik 6

我可以结合一些协程上下文,但是这样做的目的是什么,效果是什么?

协程上下文基本上是一个不可变的映射。当您组合两个不可变映射时,您将获得一个包含组成映射的所有键的映射。显然,如果两个映射都包含给定的键,则生成的映射不能包含它两次。相反,右侧地图优先。

map 范式的一个小变化是您没有将 (key, value) 对放入上下文中,而是您放入的每个值都已经有一个与之关联的键。这就是为什么每个上下文元素都已经是一个上下文本身。

例如,以下是两个成熟的上下文:

val ioCtx = Dispatchers.IO
val jobCtx = Job()
Run Code Online (Sandbox Code Playgroud)

你可以组合它们:

val ioAndJob = ioCtx + jobCtx
Run Code Online (Sandbox Code Playgroud)

您可以通过键访问元素:

val job = ioAndJob[Job]
Run Code Online (Sandbox Code Playgroud)

您可以将上下文与碰撞键结合起来:

val defaultAndJob = ioAndJob + Dispatchers.Default
Run Code Online (Sandbox Code Playgroud)

这是否意味着协程的生命周期仅限于两种上下文?

协程上下文不限制协程生命周期。需要一些外部机构在协程上下文中取消作业。您可能已经将其与CoroutineScope处理此问题的哪个混淆了。CoroutineScope只是一个具有单个属性的对象coroutineContext,但是由于协程构建器例如launchasync将其作为接收器,因此可以轻松构建可以集中取消的协程层次结构。