【问题标题】:Kotlin coroutines runBlocking asyncKotlin 协程 runBlocking async
【发布时间】:2020-11-20 16:52:31
【问题描述】:

我是协程的新手,并试图利用它们在更短的时间内多次调用一个耗时的方法

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 在所有 timeConsumingMethods 完成之前返回。

运行这个我看到 timeConsumingMethods 正在同步运行

谁能帮我理解我错过了什么错误?

【问题讨论】:

  • 您如何确定这些方法正在同步运行?
  • 记录在 timeConsumingMethod 中,显示它在下一个开始之前完成的其余调用
  • 使用async(Dispatchers.IO) { ... }
  • 是的,因为 runBlocking 是单线程的,它们会按顺序运行,但你为什么要使用 runBlocking?使功能暂停有什么问题吗?与 IR42 给出的建议相同,对于阻塞进程,请考虑使用 Dispatchers.IO(否则 Dispatchers.Default 用于 CPU 驱动的任务)。
  • callAPI 从非挂起的方法调用。实际上我最终确实使用了 Dispatchers.Default,它起作用了,所以如果 @IR42 想要做出回应,我会做出选择的答案。

标签: kotlin kotlin-coroutines


【解决方案1】:

你需要指定一个不是runBlocking的默认单线程调度器的调度器,否则什么都不能并行运行。

为了清晰/简洁,您的代码也可以重新排列一下。

fun callAPI(idList: Collection<String>): List<String> = runBlocking(Dispatchers.IO) {
    idList.map {
        async { timeConsumingMethod(it) }
    }.awaitAll()
}

如果您使用的 UI 不想在操作期间冻结,则应考虑将其设为挂起功能并在结果准备就绪时对其进行响应,而不是使用 runBlocking。

【讨论】:

    猜你喜欢
    • 2019-02-19
    • 2019-07-17
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-19
    相关资源
    最近更新 更多