我正在学习kotlin协同和作用域,无法理解如何通过不阻塞主线程来触发并行调用。正如您在下面的示例中所看到的,两个调用是并行触发的,但是对.awaitAll()的调用似乎阻塞了主线程,因为我希望“I‘s阻塞消息”将打印在“1.1.Current线程.”之前。消息。这是实现这类查询的正确方法吗?
当前产出:
主螺纹主
.(5秒后).
1.当前线程DefaultDispatcher-worker-1
1.当前线程DefaultDispatcher-worker-3
我被堵住了
预期产出:
主螺纹主
我被堵住了
.(5秒后).
1.当前线程DefaultDispatcher-worker-1
1.当前线程DefaultDispatcher-worker-3
class FindItinerariesComposable(private val providers: List<FindItineraries>) : FindItineraries {
override suspend fun itinerariesForOriginDestination(origin: String, destination: String): List<Itinerary> {
println("Main thread ${Thread.currentThread().name}")
return coroutineScope {
val stream = providers.stream()
.map {
async {
it.itinerariesForOriginDestination(origin, destination)
}
}
.toList()
.awaitAll()
.flatten()
println("I'm blocked")
stream
}
}
}
class FindItinerariesInFlightProvider(private val httpClient: HttpClient) : FindItineraries {
override suspend fun itinerariesForOriginDestination(origin: String, destination: String): List<Itinerary> {
withContext(Dispatchers.IO) {
delay(5000)
println("1.Current thread ${Thread.currentThread().name}")
}
return listOf(Itinerary("bue", "MIA", "TEST"))
}
}
fun main() = runBlocking<Unit> {
val service = FindItinerariesComposable(listOf(FindItinerariesInFlightProvider(HttpClient()),
FindItinerariesInFlightProvider(HttpClient())))
launch {
service.itinerariesForOriginDestination("BUE", "MIA")
}
}发布于 2022-02-01 06:55:22
你好像也想吃蛋糕。
在让主线程继续执行任何进一步的任务之前,您希望得到主线程上所有这些调用的结果。
您也不想阻塞主线程。
如果需要后者,则必须引入并发性,其中主线程执行其他任务,并且不需要这些结果才能继续。
这可能意味着你正在做的事情的设计发生了根本性的变化。如果您有任何依赖于这些结果的代码,那么您将不得不添加更多的代码,这些代码使用了一些暂存值或模型值,直到实际的结果可用为止。您还必须将当前接收结果并对其进行操作的任何代码移动到协同线中。
下面是一个大纲:
fun main() {
val service = initializeService()
val myScope = CoroutineScope()
myScope.launch {
val itineraries = service.itinerariesForOriginDestination("BUE", "MIA")
// do things with itineraries
}
// do other things, don't let the main function end
myScope.cancel() // do this at the very end, when you no longer
// need coroutines
}https://stackoverflow.com/questions/70933310
复制相似问题