2009-04-08 6 views
0

Dans this article MSDN (chapitre 6 - Amélioration des performances ASP.NET), il dit le texte suivant:Implémenter un WebMethod ASP.NET uniquement de façon asynchrone si vous pouvez effectuer une parallélisation?

« Évitez les appels asynchrones sauf si vous avez un travail parallèle supplémentaire

Faire des appels asynchrones à partir de votre application Web uniquement lorsque votre application a un travail parallèle supplémentaire à effectuer pendant qu'elle attend la fin des appels asynchrones et que le travail effectué par l'appel asynchrone n'est pas lié à l'UC En interne, les appels asynchrones utilisent un thread de travail du pool de threads; en effet, vous utilisez des threads supplémentaires.

En même temps que vous faites des appels d'E/S asynchrones, comme appeler une méthode Web ou effectuer des opérations de fichiers, le fil qui fait l'appel est libéré afin qu'il puisse effectuer des travaux supplémentaires, comme la fabrication d'autres appels asynchrones ou d'autres tâches parallèles. Vous pouvez ensuite attendre la fin de toutes ces tâches. Faire plusieurs appels asynchrones qui ne sont pas liés à l'UC et les laisser s'exécuter simultanément peut améliorer le débit.

Ceci est confus pour moi. Ma compréhension était que lorsque vous effectuez un appel d'E/S asynchrone qu'aucun thread n'est utilisé en attente, mais qu'un IOCP est défini avec une référence à votre méthode de rappel. Est-il vrai que vous ne devriez utiliser les appels asynchrones que lorsque vous travaillez en parallèle? Ma compréhension était que pour un service Web ASP.NET, il est souvent une bonne idée de changer un WebMethod Foo à BeginFoo/EndFoo lorsque vous appelez une opération liée E/S et mettre en œuvre le tout de manière asynchrone. Est-ce que quelqu'un peut m'aider à comprendre ce que l'on entend par «les appels asynchrones utilisent un thread de travail du pool de threads; en effet, vous utilisez des threads supplémentaires ", et la différence entre WorkerThreads et IO-threads?

Répondre

3

Il est important de distinguer clairement les opérations intensives (comme le calcul du milliardième nombre premier) et les opérations liées aux E/S (comme faire une demande de service Web).

Une opération intensive nécessite nécessite un thread pour s'exécuter, donc vous avez raison, l'utilisation de l'implémentation ASP.NET asynchrone n'a aucun avantage puisque vous utilisez toujours un thread IIS.

Les opérations liées aux E/S sont différentes, elles utilisent les ports d'achèvement des E/S du système d'exploitation et ne nécessitent pas de thread. Dans ce cas, il peut vraiment être utile d'utiliser le modèle asynchrone ASP.NET, car le traitement de la demande n'exigera qu'un thread pendant une courte période pour exécuter la requête d'E/S, puis un autre thread pendant un court instant pour traiter le rappel d'E/S. réponse. Cela peut vraiment aider l'évolutivité.

Jeff Prosise a un bon post sur le sujet ici: http://www.wintellect.com/CS/blogs/jprosise/archive/2010/03/29/asynchronous-controllers-in-asp-net-mvc-2.aspx

+0

J'ai aussi écrit un billet de blog à long (avec exemple de code) sur l'écriture des services WCF async: http://mikehadlow.blogspot.com/2011/ 03/7000-concurrentes-connexions-avec.html –

2

Chaque demande à une application ASP.NET est exécutée dans son propre thread à partir d'un pool de threads disponibles pour le processus de travail w3wp. Lorsque vous exécutez un appel asynchrone, vous effectuez en fait une requête distincte à l'application ASP.NET et utilisez un autre des threads disponibles dans le pool. Le pool est de taille fixe en fonction de la configuration de votre serveur et des limitations matérielles. Il représente le nombre maximal de requêtes que votre serveur peut effectuer à tout moment.

Les appels asynchrones sont principalement utilisés lorsque plusieurs opérations «lourdes» sont nécessaires afin de réduire le temps nécessaire pour renvoyer une page au client et, dans certains cas, pour augmenter la disponibilité globale des threads.

Pensez-y de cette façon, vous demandez une page Web qui a quatre graphiques boursiers (1 thread en cours d'utilisation). La page fait une demande au premier service de stock (1 nouveau thread + 1 ancien thread = 2 threads en cours d'utilisation.) La page reçoit les résultats (1 thread fermé, 1 thread en cours d'utilisation). La page fait une demande au deuxième service de stock (1 nouveau thread + 1 ancien thread = 2 threads en cours d'utilisation.) Et ainsi de suite. En supposant que chaque service de stock prenne quatre secondes pour répondre, vous reliez 2 threads à 16 secondes chacun pour un temps de traitement total de 32 secondes (sans compter le fait que la page des clients met 16 secondes à se charger.Ces chiffres sont tous faux bien sûr, mais sont destinés à illustrer le point. Maintenant, dans une implémentation asynchrone, vous demandez une page web qui a quatre graphiques boursiers (1 thread en cours d'utilisation.) La page fait quatre demandes pour stocker des services (1 ancien thread + 4 nouveaux threads = 5 threads en cours d'utilisation). service de stock prend quatre secondes pour répondre, vous attachant 5 threads à 4 secondes chacun pour un temps de traitement total de 20 secondes et le client a reçu la page en 4 secondes. Vous avez réduit le coût global des opérations car votre thread principal, qui ne peut pas être libéré tant que la page du client n'est pas exposée, a été utilisé pendant une période plus courte. Enfin, rien de tout cela n'a beaucoup à voir avec les threads d'E/S. L'appel d'une méthode Web asynchrone, car il contient des opérations d'E/S, ne vous apportera aucun avantage , sauf si vous avez un traitement important à effectuer pendant que vous attendez les résultats. Ou, dans les mots de l'article, "Évitez les appels asynchrones, sauf si vous avez un travail parallèle supplémentaire."

Questions connexes