Какова цель объединения контекстов сопрограмм в Kotlin? - PullRequest
4 голосов
/ 03 марта 2020

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

В официальном документе говорится, что я могу комбинировать некоторые сопрограммные контексты, но какова цель этого и каков эффект? Означает ли это, что жизненный цикл сопрограммы ограничен обоими контекстами?

Ответы [ 2 ]

4 голосов
/ 03 марта 2020

Я могу комбинировать некоторые контексты сопрограмм, но какова цель этого и каков эффект?

Контекст сопрограмм - это в основном неизменная карта. Когда вы объединяете две неизменные карты, вы получаете карту, содержащую все ключи составляющих карт. Очевидно, что если обе карты содержат заданный ключ, результирующая карта не может содержать его дважды. Вместо этого правая карта имеет приоритет.

Небольшой поворот в парадигме карты заключается в том, что вы не помещаете пары (ключ, значение) в контекст, вместо этого каждое значение, которое вы поместили, уже имеет ключ, связанный с Это. Вот почему каждый элемент контекста уже сам является контекстом.

Например, это два полноценных контекста:

val ioCtx = Dispatchers.IO
val jobCtx = Job()

Вы можете объединить их:

val ioAndJob = ioCtx + jobCtx

Вы можете получить доступ к элементу по ключу:

val job = ioAndJob[Job]

Вы можете комбинировать контексты со встречными ключами:

val defaultAndJob = ioAndJob + Dispatchers.Default

Означает ли это, что жизненный цикл сопрограммы ограничен обоими контекстами?

Контекст сопрограммы не ограничивает жизненный цикл сопрограммы. Некоторое внешнее агентство обязано отменить работу в сопрограммном контексте. Вы, вероятно, перепутали это с CoroutineScope, который решает эту проблему. CoroutineScope - это просто объект с одним свойством, coroutineContext, но поскольку компоновщики сопрограмм, такие как launch или async, принимают его как получателя, это упрощает построение иерархии сопрограмм, которая может быть централизованно отменена.

2 голосов
/ 03 марта 2020

Я думаю, что вы путаете CoroutineContext и CoroutineDispatcher (возможно, также CoroutineScope). Диспетчер - это только один вид контекста. Другие могут быть, например. Job, CoroutineName, CoroutineExceptionHandler. Вы можете объединить несколько из них - например. установить диспетчер и обработчик ошибок - но иметь только один из каждого типа.

Не имеет смысла объединять несколько диспетчеров, будет применяться только последний.

Я нашел Говорите, сопрограммы! Должен поймать их всех! Флорина Мунтенеску и Мануэль Виво из KotlinConf 2019, объясняющие некоторые из них довольно хорошо.

...