web-dev-qa-db-fra.com

Koutlin Coroutines avec valeur de retour

Je veux créer une méthode de coroutine qui a une valeur de retour.

Par exemple)

fun funA() = async(CommonPool) {
    return 1
}

fun funB() = async(CommonPool) {
    return 2
}

fun sum() {
    launch {
        val total = funA().await() + funB().await()
    }
}

Si je veux renvoyer la méthode du total en somme, comment dois-je procéder?

comme,

fun sum(): Int {
    launch {
        val total = funA().await() + funB().await()
    }   

    return total
}
4
Expert wanna be

Pour retourner exactement Int, vous devez sortir du monde coroutine et c’est à cela que runBlocking est destiné:

fun sum(): Int = runBlocking {
    funA().await() + funB().await()
}

Voir Ponter les mondes bloquants et non bloquants dans le guide de coroutine et Composition des fonctions de suspension pour savoir comment le faire si vous souhaitez utiliser sum inside coroutines.

8
Alexey Romanov

Ajout d'une autre façon de le réaliser. 

fun sum(): Int {
    var sum: Int = 0
    runBlocking {
        val jobA = async { funA() }
        val jobB = async { funB() }
        runBlocking{
           sum = jobA.await() + jobB.await()
        }
    }
    return sum
}

suspend fun funA(): Int {
    return 1
}

suspend fun funB(): Int {
    return 2
}
2
Sahil Chhabra

Il peut être tard pour répondre à cette question mais j'espère que quelqu'un le trouvera utile. L'extrait de code ci-dessous calcule la somme de 3 valeurs A + B + C. Chaque valeur est calculée indépendamment dans son propre thread d'arrière-plan en parallèle, puis tous les résultats intermédiaires sont consolidés dans un résultat final et renvoyés au thread principal pour être affichés à l'écran.

Donc, il faut 5 secondes pour calculer la valeur finale (pas 10 secondes = 2 + 3 + 5) et le résultat est évidemment 6 et il ne bloque pas, le thread principal peut gérer d'autres événements alors que l'exécution de sum () n'est pas terminée.

suspend fun sum(scheduler: ThreadPoolExecutor): Int = coroutineScope {

    withContext(scheduler.asCoroutineDispatcher()) {
        val a = async { funA() }
        val b = async { funB() }
        val c = async { funC() }

        a.await() + b.await() + c.await()
    }
}

fun funA(): Int {
    Thread.sleep(2000L)
    return 1
}

fun funB(): Int {
    Thread.sleep(3000L)
    return 2
}

fun funC(): Int {
    Thread.sleep(5000L)
    return 3
}

class MainActivity : AppCompatActivity(), View.OnClickListener {
    private val tripletsPool = ThreadPoolExecutor(3, 3, 5L, TimeUnit.SECONDS, LinkedBlockingQueue())

   ...

    override fun onClick(view: View?) {
        if (view == null) {
            return
        }

        when (view.id) {
            R.id.calculate -> {
                GlobalScope.launch(Dispatchers.Main, CoroutineStart.DEFAULT) {
                    progressBar.visibility = View.VISIBLE
                    result.setText("${sum(tripletsPool)}")
                    progressBar.visibility = View.GONE
                }
            }
        }
    }
}
0
Aleksei Mulin