Méthodes asynchrones de ApiController — quel est le bénéfice? Quand les utiliser?
(Ce qui a probablement des doublons la question ASP.NET MVC4 contrôleur Async - Pourquoi l'utiliser?, mais sur webapi, et je ne suis pas d'accord avec les réponses là)
Supposons que j'ai un long exécution de requête SQL. Ses données doivent être sérialisé en JSON et envoyée au navigateur (comme une réponse pour la demande xhr). Exemple de code:
public class DataController : ApiController
{
public Task<Data> Get()
{
return LoadDataAsync(); //Load data asynchronously?
}
}
Ce qui se passe réellement quand je fais $.getJson ("api/data', ...) (voir cette affiche http://www.asp.net/posters/web-api/ASP.NET-Web-API-Poster.pdf):
- [IIS] la Demande est acceptée par IIS.
- [IIS] IIS attend pour un thread [THREAD] de la gestion de la piscine (http://msdn.microsoft.com/en-us/library/0ka9477y(v=vs. 110).aspx) et commence à travailler en elle.
- [THREAD] Webapi Crée de nouvelles DataController objet dans ce thread, et d'autres classes.
- [THREAD] Utilise des tâches parallèles lib pour démarrer sql-query dans [THREAD2]
- [THREAD] remonte pour la gestion de la piscine, prêt pour un autre traitement
- [THREAD2] fonctionne avec sql pilote, lit les données qu'il soit prêt et invoque [THREAD3] de réponse pour la demande xhr
- [THREAD3] envoie la réponse.
N'hésitez pas à me corriger, s'il y a quelque chose de mal.
Dans la question ci-dessus, disent-ils, le point et le résultat est, que [THREAD2] n'est pas de La gestion de la Piscine, cependant l'article MSDN (lien ci-dessus) dit que
Par défaut, en parallèle de la bibliothèque de types comme
Task
etTask<TResult>
utiliser le pool de threads pour exécuter les tâches.
Je fais donc une conclusion, que tous les TROIS FILS sont gérés de la piscine.
En outre, si j'ai utilisé la méthode synchrone, je voudrais quand même garder mon serveur réactif, à l'aide d'un thread (à partir de la précieuse pool de threads).
Donc, quel est le point réel de la permutation de 1 fil à 3 fils? Pourquoi ne pas simplement de maximiser les threads du pool de thread?
Y a clairement des moyens utiles de l'aide de contrôleurs async?
Vous devez vous connecter pour publier un commentaire.
Je pense que la clé de malentendus autour de la façon dont
async
tâches de travail. J'ai unasync
intro sur mon blog qui pourrait vous aider.En particulier, un
Task
retourné par uneasync
méthode ne permet pas d'exécuter n'importe quel code. Plutôt, c'est juste un moyen pratique pour informer les appelants du résultat de cette méthode. La MSDN docs que vous avez citées ne s'appliquent aux tâches qui les fait exécuter du code, par exemple,Task.Run
.BTW, l'affiche que vous l'avez mentionné n'a rien à voir avec les threads. Voici ce qui se passe dans un
async
demande de base de données (légèrement simplifié):DataController
etc.Si vous en voulez la preuve-de-concept de code, j'ai un vieux Gist artificiellement restreint l'ASP.NET pool de threads pour le nombre de cœurs (qui est à son minimum) et ne N+1 demandes synchrones et asynchrones. Ce code ne fonctionne tout simplement un retard pour une deuxième au lieu de contacter un serveur SQL server, mais le principe général est le même.
Au profit des actions asynchrone, c'est que pendant que le contrôleur est en attente de la requête sql pour finir aucun thread n'est alloué pour cette requête, alors que si vous avez utilisé une méthode synchrone un thread serait enfermé dans l'exécution de cette méthode à partir du début à la fin de la méthode. Alors que SQL server est en train de faire son travail le fil n'est pas fait rien, mais l'attente.
Si vous utilisez des méthodes asynchrones de ce même fil peut répondre à d'autres demandes alors que SQL server est en train de faire sa chose.
Je crois que vos mesures sont mal à l'étape 4, je ne pense pas qu'il va créer un nouveau thread pour faire la requête SQL. 6 il n'y a pas créé un nouveau fil de discussion, c'est juste l'un des fils qui seront utilisés pour continuer d'où le premier thread laissé. Le fil à 6 pourrait être le même que commencé l'opération asynchrone.
J'ai mon avis la suivante décrit un avantage évident de contrôleurs async plus synchrone ceux.
de À l'aide de Méthodes Asynchrones dans ASP.NET MVC 4
Le point de async n'est pas de faire une application multithread, mais plutôt de faire un thread unique de demande de continuer avec quelque chose de différent plutôt que d'attendre une réponse d'un appel externe en cours d'exécution sur un autre thread ou processus.
Envisager un bureau application qui affiche les cours de la bourse à partir de différents échanges. L'application doit prendre une couple de REPOS /http appels pour obtenir des données à partir de chacun de la distance à la bourse de serveurs.
Un seul thread de l'application permettrait de faire le premier appel, d'attendre à ne rien faire jusqu'à ce qu'il a obtenu le premier ensemble de prix, mise à jour de la fenêtre, puis faire un appel pour le côté externe du prix des actions de serveur, de nouveau attendre à ne rien faire jusqu'à ce qu'il a obtenu le prix de mise à jour de la fenêtre... etc..
Nous pourrions aller tout de multi threaded coup d'envoi de la demande en parallèle et mise à jour de l'écran en parallèle, mais puisque la plupart du temps est consacré à l'attente d'une réponse du serveur distant, ce qui semble exagéré.
Il pourrait être mieux pour le thread:
Faire une demande pour la première serveur, mais au lieu d'attendre la réponse laisser un repère, un lieu de revenir lorsque le prix à l'arrivée et de passer à l'émission de la deuxième demande, à nouveau en laissant un marqueur d'un lieu de revenir...etc.
Lorsque toutes les demandes ont été émises à l'exécution de l'application thread peut aller à traiter avec la saisie de l'utilisateur ou de ce que jamais est nécessaire.
Maintenant, quand une réponse de l'un des serveurs est reçu, le fil peut être réalisé à partir du marqueur qui y sont énoncées précédemment et mise à jour de la fenêtre.
Tous les ci-dessus pourrait avoir été codé de longue main, mono-thread, mais il était tellement horrible va multithread est souvent plus facile. Aujourd'hui, le processus de quitter le marqueur et le retour se fait par le compilateur lorsque nous écrire async/await. Tous les mono-thread.
Il y a deux points clés ici:
1) Multi threaded ne se produisent encore! Le traitement de notre demande pour les cours de la bourse qui se passe sur un autre fil (sur une autre machine). Si nous faisions db accéder à la même chose serait vraie. Dans les exemples où l'attente est pour une minuterie, la minuterie fonctionne sur un thread différent. Notre application est bien seul thread, le point de l'exécution saute juste autour (d'une manière contrôlée) et à l'extérieur, les threads d'exécuter
2) Nous perdre le bénéfice de l'exécution asynchrone dès que l'application nécessite une opération asynchrone à compléter. Considérer une demande indiquant le prix du café à partir de deux échanges, l'application peut ouvrir la voie à des demandes et mise à jour de windows de façon asynchrone sur un seul thread, mais maintenant, si l'application a également calculé la différence de prix entre les deux échanges, il faudra attendre les appels asynchrones à compléter. C'est forcé sur nous, car une méthode asynchrone (comme l'un de nous pourrait écrire à l'appel d'un échange d'un prix de l'action) ne retourne pas le prix des actions, mais une Tâche qui peut être considéré comme un moyen de retrouver le marqueur qui a été établi de sorte que la fonction peut remplir et retourner le cours de l'action.
Cela signifie que chaque fonction qui appelle une fonction async doit être asynchrone ou à attendre que les autres thread/processus/machine" appel au bas de la pile d'appel pour terminer, et si nous sommes en attente pour le fond d'appel à pourquoi s'embêter avec async à tous?
Lors de l'écriture d'une api web, IIS ou autre hôte est l'application de bureau, nous écrivons nos méthodes de contrôleur asynchrone, de sorte que l'hôte peut exécuter d'autres méthodes sur notre fil au service d'autres demandes tout notre code est en attente d'une réponse de travailler sur un autre thread/processus/machine.