#kotlin #kotlin-coroutines
#kotlin #kotlin-сопрограммы
Вопрос:
Я новичок в сопрограммах и пытаюсь использовать их для вызова трудоемкого метода пару раз за меньшее время
fun callAPI(idList: Collection<String>): List<String> {
val storedIds = mutableListOf<String>()
runBlocking {
val ids = idList.map { data ->
async {timeConsumingMethod(data)}
}.map { it.await() }
storedIds.addAll(ids)
}
return storedIds
}
Мне нужно, чтобы все вызовы timeConsumingMethod выполнялись параллельно, но я не хочу, чтобы callAPI возвращался до тех пор, пока не завершатся все TIMECONSUMINGMETHOD .
Запустив это, я вижу, что трудоемкие методы выполняются синхронно
Может кто-нибудь помочь мне понять, какую ошибку я упускаю?
Комментарии:
1. Как вы определяете, что методы выполняются синхронно?
2. в методе timeConsumingMethod выполняется регистрация, которая показывает, что выполняемый им вызов rest завершается до запуска следующего
3. использование
async(Dispatchers.IO) { ... }
4. Да, потому что блокировка выполнения является однопоточной, они будут выполняться последовательно, почему вы используете блокировку выполнения? Возникли проблемы с приостановкой функции? И то же предложение, что и в IR42, для процесса блокировки рассмотрите возможность использования диспетчеров. Ввод-вывод (в противном случае диспетчеры. По умолчанию для задач, управляемых процессором).
5. callAPI вызывается из не зависшего метода. Я действительно в конечном итоге использовал диспетчеров. По умолчанию, который сработал, поэтому, если @IR42 захочет дать ответ, я сделаю это выбранным ответом.
Ответ №1:
Вам нужно указать диспетчер, отличный runBlocking
от однопоточного диспетчера по умолчанию, иначе ничего не сможет выполняться параллельно.
Ваш код также может быть немного изменен для ясности / краткости.
fun callAPI(idList: Collection<String>): List<String> = runBlocking(Dispatchers.IO) {
idList.map {
async { timeConsumingMethod(it) }
}.awaitAll()
}
Если вы работаете с пользовательским интерфейсом, который не хотите замораживать во время операции, вам следует подумать о том, чтобы сделать эту функцию приостановленной и реагировать на результаты, когда они будут готовы, а не использовать runBlocking
.