我有一些挂起函数在我的 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。
为了让这些并行执行,我缺少什么?
最佳答案
如果您为每个范围创建一个新范围,它们将并行启动:
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()
}
关于android - 协程不并行运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63812589/