Les méthodes d' action asynchrone sont utiles lorsqu'une action doit effectuer plusieurs opérations indépendantes de longue durée.
Une utilisation typique de la classe AsyncController est les appels de service Web de longue durée.
Mes appels de base de données doivent-ils être asynchrones?
Le pool de threads IIS peut souvent gérer beaucoup plus de demandes de blocage simultanées qu'un serveur de base de données. Si la base de données est le goulot d'étranglement, les appels asynchrones n'accéléreront pas la réponse de la base de données. Sans mécanisme de limitation, la répartition efficace de plus de travail vers un serveur de base de données débordé à l'aide d'appels asynchrones déplace simplement une plus grande partie de la charge vers la base de données. Si votre base de données est le goulot d'étranglement, les appels asynchrones ne seront pas la solution miracle.
Vous devriez jeter un oeil à 1 et 2 références
Dérivé des commentaires @PanagiotisKanavos:
De plus, async ne signifie pas parallèle. L'exécution asynchrone libère un thread de pool de threads précieux du blocage pour une ressource externe, sans complexité ni coût de performance. Cela signifie que la même machine IIS peut gérer plus de demandes simultanées, pas qu'elle s'exécutera plus rapidement.
Vous devez également tenir compte du fait que les appels bloquants commencent par un spinwait gourmand en CPU. Pendant les périodes de stress, le blocage des appels entraînera une augmentation des retards et un recyclage du pool d'applications. Les appels asynchrones évitent simplement cela
Vous pouvez trouver mon article MSDN sur le sujet utile ; J'ai pris beaucoup d'espace dans cet article décrivant quand vous devez utiliser
async
sur ASP.NET, pas seulement comment utiliserasync
sur ASP.NET.Tout d'abord, comprenez que
async
/await
consiste à libérer des threads . Sur les applications GUI, il s'agit principalement de libérer le thread GUI afin que l'expérience utilisateur soit meilleure. Sur les applications serveur (y compris ASP.NET MVC), il s'agit principalement de libérer le thread de demande afin que le serveur puisse évoluer.En particulier, il ne:
await
.await
"cède" uniquement au pool de threads ASP.NET, pas au navigateur.Je dirais qu'il est bon de l'utiliser partout où vous effectuez des E / S. Cependant, cela ne sera pas nécessairement bénéfique (voir ci-dessous).
Cependant, il est mauvais de l'utiliser pour les méthodes liées au processeur. Parfois, les développeurs pensent qu'ils peuvent obtenir les avantages
async
en appelant simplementTask.Run
leurs contrôleurs, et c'est une idée horrible. Parce que ce code finit par libérer le thread de demande en prenant un autre thread, il n'y a donc aucun avantage (et en fait, ils subissent la pénalité des commutateurs de thread supplémentaires)!Vous pouvez utiliser toutes les méthodes attendues dont vous disposez. À l'heure actuelle, la plupart des principaux acteurs soutiennent
async
, mais il y en a quelques-uns qui ne le font pas. Si votre ORM ne prend pas en chargeasync
, n'essayez pas de l'envelopperTask.Run
ou quelque chose comme ça (voir ci-dessus).Notez que j'ai dit "vous pouvez utiliser". Si vous parlez d'ASP.NET MVC avec un seul backend de base de données, vous n'obtiendrez (presque certainement) aucun avantage d'évolutivité
async
. En effet, IIS peut gérer beaucoup plus de demandes simultanées qu'une seule instance de SQL Server (ou tout autre SGBDR classique). Cependant, si votre backend est plus moderne - un cluster de serveurs SQL, Azure SQL, NoSQL, etc. - et que votre backend peut évoluer, et que votre goulot d'étranglement d'évolutivité est IIS, alors vous pouvez bénéficier d'un avantage d'évolutivitéasync
.Autant que vous voulez. Cependant, notez que de nombreux ORM ont une règle d'une opération par connexion. En particulier, EF n'autorise qu'une seule opération par DbContext; cela est vrai que l'opération soit synchrone ou asynchrone.
Gardez également à l'esprit l'évolutivité de votre backend. Si vous utilisez une seule instance de SQL Server et que votre IIS est déjà capable de maintenir SQLServer à pleine capacité, doubler ou tripler la pression sur SQLServer ne vous aidera pas du tout.
la source
Comme d'habitude en programmation, cela dépend . Il y a toujours un compromis quand on descend un certain chemin.
async-await
brille dans les endroits où vous savez que vous recevrez des demandes simultanées à votre service et que vous souhaitez pouvoir évoluer correctement. Commentasync-await
aide à évoluer? Dans le fait que lorsque vous appelez un appel d'E / S asynchrone de manière synchrone , tel qu'un appel réseau ou que vous frappez votre base de données, le thread actuel qui est responsable de l'exécution est bloqué en attendant la fin de la demande. Lorsque vous utilisezasync-await
, vous activez le framework pour créer une machine d'état pour vous qui s'assure qu'après l'appel d'E / S est terminée, votre méthode continue de s'exécuter là où elle s'était arrêtée.Une chose à noter est que cette machine d'état a une surcharge subtile. Rendre une méthode asynchrone ne la fait pas exécuter plus rapidement , et c'est un facteur important à comprendre et une idée fausse que beaucoup de gens ont.
Une autre chose à prendre en considération lors de l'utilisation
async-await
est le fait qu'elle est asynchrone tout le long , ce qui signifie que vous verrez l'async pénétrer toute votre pile d'appels, de haut en bas. Cela signifie que si vous souhaitez exposer des API synchrones, vous vous retrouverez souvent à dupliquer une certaine quantité de code, car l' async et la synchronisation ne se mélangent pas très bien.Si vous choisissez de suivre le chemin de l'utilisation des appels d'E / S asynchrones, alors oui,
async-await
sera un bon choix, car de plus en plus de fournisseurs de bases de données modernes exposent la méthode asynchrone implémentant le TAP (Task Asynchronous Pattern).Autant que vous le souhaitez, tant que vous suivez les règles énoncées par votre fournisseur de base de données. Il n'y a pas de limite au nombre d'appels asynchrones que vous pouvez effectuer. Si vous avez des requêtes indépendantes les unes des autres et pouvant être effectuées simultanément, vous pouvez effectuer une nouvelle tâche pour chacune et utiliser
await Task.WhenAll
pour attendre la fin des deux.la source
scale out well
puisse signifieryour server won't die under load
. Ou cela peut être un cas deonce burned ...
Mes 5 cents:
async/await
si et seulement si vous effectuez une opération d'E / S, comme une base de données ou un service Web de service externe.PS Il existe des cas exceptionnels pour le point 1, mais vous devez avoir une bonne compréhension des internes asynchrones pour cela.
Comme avantage supplémentaire, vous pouvez effectuer quelques appels IO en parallèle si nécessaire:
la source
async
les actions sont plus utiles lorsque les actions effectuent des opérations d'E / S vers la base de données ou certains appels liés au réseau où le thread qui traite la demande sera bloqué avant qu'il ne reçoive la réponse de la base de données ou de l'appel lié au réseau que vous venez d'appeler. Il est préférable que vous les utilisiez avec eux et cela améliorera vraiment la réactivité de votre application (car moins de threads d'entrée / sortie ASP seront bloqués en attendant la base de données ou toute autre opération comme celle-ci). Dans toutes mes applications, chaque fois que de nombreux appels à la base de données sont très nécessaires, je les ai toujours enveloppés dans une méthode accessible et j'ai appelé cela avec unawait
mot clé.la source
Comme vous le savez, MVC prend en charge les contrôleurs asynchrones et vous devriez en profiter. Dans le cas où votre contrôleur effectue une opération longue (il peut s'agir d'une E / S sur disque ou d'un appel réseau vers un autre service distant), si la demande est traitée de manière synchrone, le thread IIS est occupé tout le temps. Par conséquent, le thread attend simplement la fin de la longue opération. Il peut être mieux utilisé en servant d'autres demandes pendant que l'opération demandée en premier est en cours. Cela vous aidera à traiter plus de demandes simultanées. Votre service Web sera hautement évolutif et ne rencontrera pas facilement le problème C10k . C'est une bonne idée d'utiliser async / wait pour les requêtes db. et oui, vous pouvez les utiliser autant de fois que vous le jugez utile.
Jetez un œil ici pour d'excellents conseils.
la source
D'après mon expérience, de nombreux développeurs utilisent aujourd'hui
async/await
par défaut les contrôleurs.Ma suggestion serait de l' utiliser uniquement lorsque vous savez que cela vous aidera .
La raison en est que, comme Stephen Cleary et d'autres l'ont déjà mentionné, cela peut introduire des problèmes de performances plutôt que de les résoudre, et cela ne vous aidera que dans un scénario spécifique:
la source
Il est bon de le faire partout où vous pouvez utiliser une méthode asynchrone, en particulier lorsque vous rencontrez des problèmes de performances au niveau du processus de travail, ce qui se produit pour des données massives et des opérations de calcul. Sinon, pas besoin car les tests unitaires devront être lancés.
Oui, il est préférable d'utiliser async pour toute opération de base de données autant que possible pour éviter les problèmes de performances au niveau des processus de travail. Notez qu'EF a créé de nombreuses alternatives asynchrones pour la plupart des opérations, telles que:
Le ciel est la limite
la source