Каждая приостановляемая функция имеет доступ к глобальной переменной coroutineContext
, которую вы можете тривиально обернуть в CoroutineScope
, но это не ее целевое назначение. Это там, так что вы можете в любой момент проверить, была ли отменена ваша сопрограмма, получить отладочную информацию, такую как имя задания и т. Д.
По словам Романа Елизарова в его недавнем Medium post :
suspend fun doNotDoThis() { CoroutineScope(coroutineContext).launch { println("I'm confused") } }
Не делайте этого!
blockquote>Приостановленная функция не должна запускать параллельную работу, которая может продолжаться после ее возврата. Он должен использовать только параллелизм для достижения параллельной декомпозиции задачи, а это значит, что он будет ждать завершения всех дочерних сопрограмм.
Вы должны решить либо использовать простую функцию, которая является получателем
CoroutineScope
(сигнализирующую о намерении начать параллельную работу) , либо использовать функцию приостановки, которая ожидает завершения всей работы, которую она инициировал.Итак, если вы хотите параллельную декомпозицию, то используйте блок
coroutineScope
или, возможно,supervisorScope
:coroutineScope { launch { // ... task to run in the background } // ... more work while the launched task runs in parallel } // All work done by the time we reach this line
coroutineScope
является приостановленной функцией, и она не будет завершена, пока все сопрограммы были запущены полностью.
Вы можете создать функцию расширения на CoroutineScope
или функцию с CoroutineScope
в качестве параметра:
fun CoroutineScope.doThis() {
launch { ... }
}
fun doThatIn(scope: CoroutineScope) {
scope.launch { ... }
}
Также вы можете использовать coroutineScope
или [ 115] , в зависимости от ваших потребностей:
suspend fun someFun() = coroutineScope {
launch { ... }
}
suspend fun someFun() = supervisorScope {
launch { ... }
}
Вы можете просто использовать withContext()
или coroutineScope()
для запуска другой сопрограммы:
withContext(coroutineContext) {
launch { ... }
}
В то время как вторая переопределяет Job
контекста, но повторно использует контекст: