有没有一种方法可以 运行 在多个线程上编写代码,以便更快地执行它,然后等待所有线程完成?

Is there a way how I can run code on multiple threads so it gets executed faster and then wait for all of them to complete?

我有 2 个函数,我需要先完成第一个,然后再完成第二个,但是 运行 它在一个线程上花费了很长时间,所以我尝试 运行 就像使用 CoroutineScope 一样, 但即使没有下载所有图像,第二个函数也会执行。

downloadSkillsImages(context)      
addSkillsToDB()
private suspend fun downloadSkillsImages(context: Context) {
        for (i in 0 until skills.size) {
            CoroutineScope(IO).launch {
                try {
                    val url = fbStorage.reference.child("skillImagesMini").child("${skills[i].skillId}.jpg").downloadUrl.await()
                    skills[i].skillImage = getBitmapFromUri(url, context)
                }catch (e: Exception){
                    //image not found, nothing happens
                }
            }
        }
    }

这就是 coroutineScope 作用域函数的用途。它等待所有子协程完成。

private suspend fun downloadSkillsImages(context: Context) = coroutineScope {
    for (i in skills.indices) {
        launch(Dispatchers.IO) {
            try {
                val url = fbStorage.reference.child("skillImagesMini").child("${skills[i].skillId}.jpg").downloadUrl.await()
                skills[i].skillImage = getBitmapFromUri(url, context)
            } catch (e: Exception){
                //image not found, nothing happens
            }
        }
    }
}

注意,如果 getBitmapFromUri 是阻塞函数,您只需要指定 Dispatchers.IO。如果它是一个挂起函数,那么这个子协程中没有任何东西是阻塞的,所以使用什么调度程序来调用它并不重要。

由于您希望协程全部完成并默默地忽略失败的协程,因此您可以使用 supervisorScope 而不是 coroutineScope 来简化这一点,因此您不需要 try/catch . supervisorScope 将成功完成,即使其某些子项失败。

private suspend fun downloadSkillsImages(context: Context) = supervisorScope {
    for (i in skills.indices) {
        launch(Dispatchers.IO) {
            val url = fbStorage.reference.child("skillImagesMini").child("${skills[i].skillId}.jpg").downloadUrl.await()
            skills[i].skillImage = getBitmapFromUri(url, context)
        }
    }
}