Kotlin协程并行化
我在并行启动协同程序时遇到一些问题 我有一些代码可以在协同路由中发出网络请求,这个网络请求返回一个中间结果的集合,我想并行地(即不是顺序地)获取这个集合中每个项目的完整结果 以下是相关的API:Kotlin协程并行化,kotlin,kotlin-coroutines,Kotlin,Kotlin Coroutines,我在并行启动协同程序时遇到一些问题 我有一些代码可以在协同路由中发出网络请求,这个网络请求返回一个中间结果的集合,我想并行地(即不是顺序地)获取这个集合中每个项目的完整结果 以下是相关的API: data class IntermediateResult(val id: Long) data class FinalResult(val id: Long, val name: String) suspend fun getIntermediateResults() : Collection&l
data class IntermediateResult(val id: Long)
data class FinalResult(val id: Long, val name: String)
suspend fun getIntermediateResults() : Collection<IntermediateResult>
suspend fun getFinalResult(id: Long) : FinalResult
我的理解是,在forEach
循环中启动一个新的协程将导致以并行方式获取每个项目的最终结果(即,在继续forEach的下一次迭代之前,它不会“等待”到getFinalResult
),但是,我观察到它是按顺序发生的(即,forEach循环中对getFinalResult
的调用导致代码在开始下一次迭代之前“等待”直到结果返回)
换句话说,我不关心最终结果是按照迭代的顺序返回到中间结果
如果相关(我相当肯定不是)两个挂起函数的实现是使用
suspendcorroutine
将旧的回调类型代码封装到挂起函数中。GUI是否也冻结?您使用的是Main
调度程序,因此如果getFinalResult
不是挂起函数,则应该这样做。如果getFinalResult
already是一个正确实现的可挂起函数,它使用一个底层异步网络API,那么请求应该并行执行,并且至少GUI不应该冻结。但是,如果GUI保持活动状态,而您没有收到并行请求,那么这可能取决于网络库的实现/配置de>getFinalResult是一个挂起函数(它使用SuspendCorroutine
包装旧的回调样式代码)。GUI冻结是的,但如果使用viewModelScope.launch(Dispatchers.Default),我会观察到相同的行为
。我建议将重点放在冻结GUI上,如果正确实现和使用了暂停,就不应该发生冻结GUI。
fun example() {
viewModelScope.launch(Dispatchers.IO) {
val intermediateResults = getIntermediateResults()
intermediateResults.forEach { intermediateResult ->
viewModelScope.launch(Dispatchers.IO) {
val finalResult = getFinalResult(intermediateResult.id)
// Update cache and post updated cache to the UI via live data
}
}
}
}