我有一些挂起函数可以在我的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。
要让它们并行执行,我缺少什么?
答案 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()
}