0
votes

Lancez un certain nombre de coroutines et joignez-les tous avec le délai d'attente (sans annuler)

Je dois lancer un certain nombre d'emplois qui retourneront un résultat.

dans le code principal (qui est pas a coroutine), après avoir lancé les travaux, j'ai besoin d'attendre que tous remplir leur tâche ou pour un délai donné pour expirer, quel que soit la première éventualité.

Si je sors de l'attente parce que tous les emplois sont terminés avant le délai d'attente, c'est génial, je collectionnerai leurs résultats.

Mais si certains des emplois prennent plus de temps que le délai d'attente, ma fonction principale doit se réveiller dès que le délai d'expiration expire, inspectez les emplois terminés à temps (le cas échéant) et lesquels sont toujours en cours d'exécution et fonctionnent de Là, sans annule les travaux qui fonctionnent toujours.

Comment voudriez-vous coder ce genre d'attente?


0 commentaires

3 Réponses :



0
votes

Voici la solution que j'ai proposée. Associant chaque travail avec un état (entre autres): xxx

et écrire une boucle explicite: xxx

L'état initial est appelé attente (au lieu de courir) parce que cela ne signifie pas nécessairement que le travail est toujours en cours d'exécution, seulement que ma boucle n'a pas encore pris en compte.

Je suis intéressé à savoir si cela est assez idiomatique, ou s'il y a de meilleurs moyens de coder ce type de comportement.


0 commentaires

1
votes

La solution suit directement de la question. Premièrement, nous concevons une fonction de suspension pour la tâche. Voyons nos exigences:

Si certains des emplois prennent plus de temps que le délai d'attente ... sans annuler les travaux qui fonctionnent toujours. P> blockQuote>

Cela signifie que les travaux que nous avons lancés doivent être autonomes (non enfants), nous allons donc vous désactiver la concurrence structurée et utiliser globalscope code> pour les lancer, collectant manuellement tout les emplois. Nous utilisons async code> COROUTINE CONSTRUILDER, car nous prévoyons de collecter leurs résultats de certains types R code> ultérieurement: p> xxx pré>

Après avoir lancé les emplois, j'ai besoin de les attendre pour tous remplir leur tâche ou pour un délai donné pour expirer, selon la première éventualité. P> blockQuote>

Attendons-les tous et faites-le en attente avec le délai d'attente: p> xxx pré>

Nous utilisons joinall code> (par opposition à attendu code>) Pour éviter d'exception si l'un des travaux échoue et avectimeOutNull code> pour éviter l'exception sur le délai d'attente. P>

Ma fonction principale doit se réveiller dès que le délai d'expiration expire, inspecter les emplois terminés à temps (le cas échéant) et lesquels sont toujours en cours d'exécution p> blockQuote> xxx pré>

dans le code principal (qui n'est pas une coroutine) ... p> BlockQuote>

Étant donné que notre code principal n'est pas une coroutine, il doit attendre de manière bloquante, donc nous comblions le code que nous avons écrit à l'aide de Runblocking code>. Mettre tout ensemble: P>

fun awaitResultsWithTimeoutBlocking(
    timeoutMillis: Long,
    numberOfJobs: Int
) = runBlocking {
    val jobs: List<Deferred<R>> = List(numberOfJobs) { 
        GlobalScope.async { /* our code that produces R */ }
    }    
    withTimeoutOrNull(timeoutMillis) { jobs.joinAll() }
    jobs.map { deferred -> /* ... inspect results */ }
}


0 commentaires