Nous construisons une application ASP.NET CORE 3.1. Il contient une page une liste des éléments de travail et un formulaire qui permet à quelqu'un d'être attribué à quelqu'un. Si l'action du contrôleur réussit, il se termine par une redirection à l'action qui montre les éléments de travail une fois de plus.
Il a remarqué que la liste est parfois rechargée avec des éléments avec l'ancienne affectation et un rafraîchissement obtient alors la liste mise à jour.
Le contrôleur Obtenir une action pour la liste est ASYNC, avec un attendre pour le code qui reçoit la liste des éléments, avec un code imbriqué pour obtenir le formulaire de données de la base de données avec une requête LINQ vers des entités avec Le contrôleur post-action est également asynchronisé, mais sans rien attendre. p> Cependant, le code étant appelé contient une construction comme celle-ci: p> j'ai simplifié le code assez Un peu, et j'espère que je n'ai pas introduit des incohérences avec ça ... em> p> Je me demande comment cela fonctionne réellement. P> La boucle est traitée avec un instruction code> async code>. Ce code attend Tolistasync () code>. p>
firstordfaultontasync () code> et
SAVECHANGESASYNC () code>, mais seulement dans la boucle. La journalisation révèle que la méthode elle-même renvoie avant que toutes les tâches attendues sont terminées. P>
Getting work items
Start assigning items
Start assigning item 1234
Start assigning report 2345
Done assigning item
Redirecting to work items
Getting work items
Done assigning item 1234
Done assigning item 2345
3 Réponses :
Votre méthode code> Assign code> doit être async:
Bien que cela empêche assigner code> de retourner à tôt, il est également extrêmement inefficace. Chaque opération de base de données se produit de manière séquentielle, ce qui pourrait prendre un temps important pour un grand nombre d'éléments.
Je ne vois pas cela comme le problème principal ici. Juste répondre à la question. Les opérations de base de données simultanées ne sont pas toujours plus rapides que les opérations de lot.
array.foreach code> prend dans un
action
async vide code>. En raison de la signature étant
void code> et non de la tâche code>, le délégué ne peut pas être attendu. Ainsi le marquer comme
async code> et en utilisant
attendre code> à l'intérieur vous donne un faux sentiment d'exactitude lorsque c'est en fait le contraire. Vous devrez changer votre méthode code> code>
async tâche code>, puis mettre en œuvre la suggestion de @Paulo Morgado. P>
Vous passez un délégué asynchrone à comme mentionné par @johanp, faire votre remarque comment à l'aide de puis dans votre contrôleur: p> array.foreach code>, mais vous n'êtes pas en attente de l'achèvement des tâches générées.
Array. Foreach code> ne fonctionne pas bien avec le code ASYNC, car il accepte un délégué
Action
assigner code> méthode
async code>: p>
Tâche.Lqus code> assure que tous les Les tâches ont été attendues avant que votre méthode ne soit autorisée à revenir. p>
énumérable.Sélectionnez code> permettra au travail ASYNC de se produire en parallèle, contrairement au
foreach code> Approche suggérée par @Paulo. p>
SAVECHANGESASYNC code> doit être appelé une fois, après toutes les tâches terminées, pour éviter les problèmes de concurrence; Cette approche réduira également la charge de la base de données. P>