0

J'ai un scénario où je dois exécuter la liste des étudiants en parallèle/indépendamment une fois que j'ai la liste des étudiants. Cependant quand je cours ceux avec le code un peu suivant, le programme se termine sans compléter correctement.C# attend des sorties de processus sans exception

public async Task ProcessStudents() 
{ 
    var students = await GetStudentsAsync().ConfigureAwait(false); 
    ProcessSingleStudent(students); 
} 

private static ProcessSingleStudent(IEnumerable<StudentModel> students) 
{ 
    students.ForEach(async student => 
    { 
     await ValidateSingleStudentAsync(student).ConfigureAwait(false); 
    } 
} 

private async Task ValidateSingleStudentAsync(StudentModel student) 
{ 
    //Do some validations here 
    if(validate) 
    { 
     var updated = await UpdateStudentAsync(student).configureAwait(false); //<== This cause issue 
    } 
} 

Comme je vois UpdateStudentAsync causant problème, que si aller avec F10 cette méthode ne retourne rien et arrête application de la console. Même j'ai mis tous les appels try-catch Je n'ai rien trouvé. Si j'interviens dans chaque point de débogage, j'obtiens le résultat attendu.

Impossible de comprendre où se situe le problème.

+0

Où est le code de 'UpdateStudentAsync'? –

+0

S'il vous plaît, partagez le code où 'ValidateSingleStudentAsync' est invoqué et donnez plus d'informations sur l'application principale, cela signifie: Est en cours sur Windows Form App ou Console App, si' ValidateSingleStudentAsync'' est exécuté dans un contexte temporaire, etc –

+0

est ce que vous avez besoin https://stackoverflow.com/a/39174582/782754 –

Répondre

1

Votre ProcessSingleStudent n'attend pas les résultats de chaque appel dans foreach. Ainsi, il se termine après itérer

Vous voulez quelque chose comme ceci: https://stackoverflow.com/a/15136833/8302901

+0

Vous aviez raison, au lieu d'exécuter la méthode asynchrone dans foreach, j'ajoute la tâche de retour dans une liste de tâches, puis en passant cette liste de tâches à 'Task.WhenAll() ' – Kenz

0

Rappelez-vous que async-est contagieuse ou await méthode ProcessSingleStudent n'est pas lui-même async, il est synchrone. Qu'est-ce que vous avez besoin est quelque chose comme

private async Task ProcessSingleStudent(IEnumerable<StudentModel> students) 
{ 
    await students.ForEach(async student => 
    { 
     await ValidateSingleStudentAsync(student).ConfigureAwait(false); 
    }).ConfigureAwait(false) 
} 

Mais cela est impossible (il ne compile pas) sans un peu d'aide d'une bibliothèque nommée AsyncEnumerator.

Le code devient

private async Task ProcessSingleStudent(IEnumerable<StudentModel> students) 
    { 
     await students.ParallelForEachAsync(async student => 
     { 
      await ValidateSingleStudentAsync(student).ConfigureAwait(false); 
     }, 
     maxDegreeOfParalellism: 30, 
     cancellationToken: null, 
     breakLoopOnException: true 
     ).ConfigureAwait(false) 
    } 
+0

Je ne pense pas que le premier bloc de code soit possible d'ajouter la méthode 'ForEach'. – Kenz

+0

Non, je l'ai dit. Peut-être que je ne me suis pas fait comprendre à ce sujet. –