协程不并行运行

时间:2020-09-09 13:19:37

标签: android kotlin kotlin-coroutines

我有一些挂起函数可以在我的WorkManager中进行网络调用,因此我试图使用协程并行运行,因此我试图在其中使用async,但它们似乎仍然按顺序执行。

示例:

suspend fun call1() = withContext(Dispatchers.IO){
    async{
        Log.d(TAG,"Call 1 started")
        delay(2000)
        Log.d(TAG,"Call 1 fiished")
    }
}

suspend fun call2() = withContext(Dispatchers.IO){
    async{
        Log.d(TAG,"Call 2 started")
        delay(5000)
        Log.d(TAG,"Call 2 finished")
    }
}

suspend fun call3() = withContext(Dispatchers.IO){
    async{
        Log.d(TAG,"Call 3 started")
        delay(1000)
        Log.d(TAG,"Call 3 finished")
    }
}

我这样称呼他们

override suspend fun doWork(): Result{
    setForeground(createForegroundInfo())
    call1()
    call2()
    call3()
    return Result.success()
}

运行此命令时,我看到日志消息按调用时的顺序显示,并且下一个调用要等到上一个结束时才开始。我期望的是call3首先完成,然后call1,最后是call2,但是它只会得到call1,call2,call3。

要让它们并行执行,我缺少什么?

1 个答案:

答案 0 :(得分:2)

如果为每个范围创建一个新范围,则它们将同时启动:

suspend fun call1() = CoroutineScope(Dispatchers.IO).launch {
    Log.d(TAG, "Call 1 started")
    delay(2000)
    Log.d(TAG, "Call 1 fiished")
}

更新:

尽管上述解决方案可以并行工作,但是您无法跟踪可能导致执行泄漏的协程。为了保留结构并发,最好像下面这样:

suspend fun call1() = withContext(Dispatchers.IO) {
    Log.d(TAG, "Call 1 started")
    delay(2000)
    Log.d(TAG, "Call 1 fiished")
}

suspend fun call2() = withContext(Dispatchers.IO) {
    Log.d(TAG, "Call 2 started")
    delay(5000)
    Log.d(TAG, "Call 2 finished")
}

suspend fun call3() = withContext(Dispatchers.IO) {
    Log.d(TAG, "Call 3 started")
    delay(1000)
    Log.d(TAG, "Call 3 finished")
}

然后:

override suspend fun doWork(): Result{
    setForeground(createForegroundInfo())

    coroutineScope {
        launch { call1() }
        launch { call2() }
        launch { call3() }
    }
    Log.d(TAG, "After all finishings")

    return Result.success()
}