L'utilisation correcte de l'attendent async en webapi
J'ai un WebApi que pour chaque requête entrante, les appels de séparer les 2 webservices, effectue un post-traitement et renvoie les résultats.
Le premier webservice appel est mis en cache localement pendant 1 heure, et les données en ce qui détermine la requête de la 2ème webservice. La 2ème webservice est appelée sur chaque demande entrante. Après que la 2e demande est faite, chaque résultat est traitée avec une logique d'entreprise et renvoyé à la réponse du client.
L'appel à la 2ème webservice ne peut pas être asynchrone, car c'est à l'aide d'un 3ème partie dll qui ne permet pas le mot clé await. Ce que j'ai fait, est enveloppé le 2ème appel webservice et de post-traitement dans une fonction async, qui est appelée à partir du contrôleur.
///api/controller/news?key=a&state=b
public async Task<HttpResponseMessage> GetNews(string key, string state)
{
//call to first webservice if not in cache
if (JsonConfig != null && JsonConfig.Configuration.NewsQuery.ContainsKey(key))
{
var results = await SearchProxyProvider.Search(filters.All, filters.Any, filters.None, filters.Sort, 100, 0, true, state, true);
int totalCount = results.TotalCount;
return Request.CreateResponse(HttpStatusCode.OK, results);
}
}
//Helper class method
public async Task<ItemCollection<Item>> Search(List<FieldValuePair> allFilters, List<FieldValuePair> anyFilters, List<FieldValuePair> noneFilters, SortedFieldDictionary sortBy, int pageSize = 100, int pageNumber = 0, bool exact = true, string stateFilter = null, bool getAllResults = true)
{
//call to 2nd api
search = SomeApi.Search(allFilters, anyFilters, noneFilters, pageSize, pageNumber, exact,
sortBy, null, WebApiConstant.Settings.CustomFields, true);
//post processing on search results
return search;
}
Parce que l'appel à la première webservice est mis en cache localement, je ne vois pas vraiment un avantage énorme à faire de ce asynchrone.
Je suis juste à la recherche pour voir si cette approche est totalement faux, de droite ou de.
En regardant 1000 utilisateurs simultanés. Il y aura plusieurs serveurs d'équilibrage de charge de la webapi, 2-3. Une première application de téléchargement de 400 utilisateurs est prévu.
OriginalL'auteur mickyjtwin | 2013-08-13
Vous devez vous connecter pour publier un commentaire.
Vous pouvez faire quelques trucs avec
AsyncLazy<T>
(par exemple, à partir de mon blog) et cache à la place. Qui donne à votre demande une façon de (de manière asynchrone) d'attente pour une actualisation, et vous n'aurez pas frapper Service1 à plusieurs reprises lorsque vous avez besoin pour actualiser les données, quel que soit le nombre de demandes simultanées.Qui est une déception. Ne s'appuyer dessus pour le fixer. 🙂
Il n'y a pas de point de que la. Le compilateur va vous avertir que votre "async" la méthode est en fait synchrone.
Si elle est synchrone, puis il suffit de l'appeler de manière synchrone. Du côté du serveur, il n'y a aucun point en l'enveloppant dans
Task.Run
ou quelque chose comme ça.J'ai quelques diapositives disponibles à partir d'un Async "sur le Serveur" parler j'ai donné lundi à ThatConference, qui peuvent vous être utiles. (Ils ont des animations de façon asynchrone demandes sont traitées et pourquoi "faux asynchrone" méthodes n'aide pas sur le côté serveur).
Vous ne devriez pas. Vous pouvez l'envelopper dans
Task.Run
, mais que de ne pas obtenir quoi que ce soit vous. L'ensemble de point deasync
dans WebAPI est de réduction le nombre de threads, de sorte que vous ne voulez pas de file d'attente de travail pour le pool de threads. Si cette explication n'est pas claire, alors pensez à la réponse à cette question: Pourquoi dois-je voulez pour faire asynchrone?Pouvez-vous m'indiquer la direction de certains détaillée des livres à ce sujet? J'aimerais vraiment entrer dans les entrailles de ce qui se passe et de comprendre ce sur une plus impliqués.
Stephen, y aurait-il pas avantage à conserver async pour la GetNews méthode et l'envelopper synchrone SomeApi.Code de la recherche dans la Tâche.Exécuter? En supposant que SomeApi.La recherche ne peut pas être modifié et reste le même, êtes-vous ce qui suggère que async les claviers doivent être retirés de ces deux fonctions? Je vous remercie.
Autant que je sache, il n'y a pas de livres qui traitent spécifiquement de
async
sur le côté serveur. Il y a un grand la vidéo sur Channel 9 mais d'autres que les meilleures ressources que je sais de ma propre blog et faites glisser le pont (j'espère que je vais afficher une vidéo dans une couple de semaines).OriginalL'auteur Stephen Cleary
À rendre la fonction de Recherche vraiment async l'appel à SomeApi.La recherche peut être enveloppé dans une tâche séparée et puis attendu. Aussi il est recommandé de mettre le code dans la première fonction d'une tâche, à votre charge les estimations de validation du cache peut-être aussi un goulot d'étranglement.
Task.Run
est mieux queStartNew
pourasync
code.Que pensez-vous de la classe comme de véritables asynchrone puis pour le côté serveur webapi?
J'utilise le terme "vraiment asynchrone" pour les méthodes asynchrones qui ne sont pas de file d'attente de travail pour le pool de threads. Sur le côté serveur, l'ensemble du point de
async
est de libérer de threads de travail, et si vous êtes en libérant un thread de travail par la mise en attente du travail pour le pool de threads (pour être exécuté par un autre thread de travail), vous ne gagnez rien. Otoh, que, cette technique est utile pourasync
sur le client, parce que ce qui compte c'est de libérer de l' UI thread. Ainsi, vous pouvez faire la queue de travail du pool de threads, et c'est bien que parce qu'il n'est pas fait sur le thread d'INTERFACE utilisateur.Merci pour vos commentaires. Je vais regarder dans les diapositives que vous avez mentionné avant j'ai fait un commentaire sur "faux async". En ce qui concerne votre féliciter au sujet de la Tâche.Run, je pense qu'il serait mieux si vous l'avez mentionné cette Tâche.Run est juste une courte alternative à la Tâche.Usine.StartNew. Le mot "mieux" est un peu trop générale.
Le phrasé que j'utilise habituellement est "
Task.Run
est préféré auTaskFactory.StartNew
pourasync
code. pourquoi." Mais "mieux" n'est pas incorrect. Le problème avecStartNew
est que c'est tellement facile à utiliser de manière incorrecte, par exemple, l'oubli de laTaskScheduler
argument (qui doit toujours être spécifiés - certains détails sont dans Stephen Toub le blog post).OriginalL'auteur Alex S