Запуск сопрограмм из приостановленной функции - PullRequest
3 голосов
/ 11 марта 2019

Учитывая, что у нас есть функция приостановки, но this не является CoroutineScope, как мы можем запускать другие сопрограммы, которые связаны с текущей областью действия того, что выполняет эту функцию suspending?

Ответы [ 3 ]

3 голосов
/ 11 марта 2019

Каждая приостановляемая функция имеет доступ к глобальной переменной coroutineContext, которую вы можете просто обернуть в CoroutineScope, но это не ее целевое назначение.Это там, так что вы можете в любой момент проверить, была ли отменена ваша сопрограмма, получить отладочную информацию, такую ​​как название работы и т. Д.

По словам Романа Елизарова в его недавнем Medium post :

suspend fun doNotDoThis() {
    CoroutineScope(coroutineContext).launch {
        println("I'm confused")
    }
}

Не делайте этого!

Приостановленная функция не должна запускать параллельную работу, которая может продолжаться после ее возврата.Он должен использовать только параллелизм для достижения параллельной декомпозиции задачи, а это означает, что он будет ожидать завершения всех дочерних сопрограмм.

Вы должны решить либо использовать простую функцию, которая получает 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 - это приостанавливаемая функция, и она не завершится, пока не завершатся все запущенные ею сопрограммы.

0 голосов
/ 11 марта 2019

Вы можете просто использовать withContext() или coroutineScope() для запуска другой сопрограммы:

withContext(coroutineContext) {
    launch { ... }
}

В то время как вторая переопределяет Job контекста, но повторно использует контекст:

coroutineScope {
    launch { ... }
}
0 голосов
/ 11 марта 2019

Вы можете создать функцию расширения для CoroutineScope или функцию с CoroutineScope в качестве параметра:

fun CoroutineScope.doThis() {
    launch { ... }
}

fun doThatIn(scope: CoroutineScope) {
    scope.launch { ... }
}

Также вы можете использовать coroutineScope или supervisorScope, в зависимости от ваших потребностей:

suspend fun someFun() = coroutineScope {
    launch { ... }
}

suspend fun someFun() = supervisorScope {
    launch { ... }
}
...