2010-02-27 4 views
0

lecture à travers le SendAsync, BeginAsync illustrations méthode de Socket s, j'ai réalisé qu'il a été suggéré de mettre en commun SocketAsyncEventArgs cas dire qu'il est mieux que BeginXX, l'approche de EndXX puisque chaque appel crée une instance IAsyncResult.Pooling .NET IAsyncResult Objets

Je pensais que ce n'était pas une bonne pratique pour regrouper des objets qui peuvent être instanciés facilement (tels que SocketAsyncEventArgs). L'allocation d'objets est assez rapide et GC est optimisé pour gérer efficacement les objets vivants. J'ai essayé cela en implémentant un mécanisme de mise en commun pour voir comment il fonctionne, en fait l'allocation est plus rapide sur des objets simples qui ne font qu'encapsuler certaines données dans ctor. (Eh bien, c'était comme profiler un SGBD en envoyant des milliards de déclarations SELECT 1, c'est pourquoi je suis ici.)

Je ne demande pas quel est le meilleur, je crois que le profilage de l'application réelle donnerait la réponse, mais juste curieux sur les avantages de la mise en commun de simples objets vivants de courte durée. Meilleure performance du GC? Fragmentation de la mémoire faible? Cela vaut-il la peine de le prendre en compte lors de la conception?

De MSDN

La principale caractéristique de ces améliorations est l'évitement de l'allocation répétée et la synchronisation des objets pendant haut volume prise asynchrone des E/S. Le modèle de conception Begin/End actuellement implémenté par la classe System.Net.Sockets.Socket nécessite qu'un objet System.IAsyncResult soit alloué pour chaque opération de socket asynchrone .

Dans les nouvelles améliorations de la classe System.Net.Sockets.Socket , les opérations de prise asynchrone sont décrits par des objets réutilisables SocketAsyncEventArgs alloué et maintenu par l'application . Applications socket haute performance connaissent mieux la quantité de opérations de socket chevauchées qui doivent être maintenues . L'application peut créer autant d'objets SocketAsyncEventArgs qu'il lui faut . Par exemple, si un serveur l'application doit avoir 15 prise acceptent les opérations en cours à tous les fois pour soutenir les taux de connexion client entrants, il peut allouer 15 SocketAsyncEventArgs réutilisables objets à cette fin.

Merci.

+0

Où avez-vous lu la suggestion? MSDN? Pourriez-vous le lier? Deuxièmement, sur quel type de code de socket travaillez-vous? S'agira-t-il de nombreux clients ou de certains clients ayant de grandes quantités de données. Personnellement, j'éviterais d'ajouter de la complexité à moins que cela ne soit explicitement requis et dans de nombreuses applications, cela ne vaut pas le coup. –

+0

@dr. evil Ajouté la référence. Environ 100 clients envoient 3-5 petits paquets par seconde. Je crée également des objets "Message" pour chaque paquet, donc je me demandais si je devais les regrouper. –

+1

Je pense que vous serez plus que bien pour 100 clients 3-5 paquets par seconde. Je ne pense pas que vous ayez besoin de regrouper le Message non plus (assurez-vous simplement qu'il est correctement éliminé). Gestion de la mémoire .NET peut gérer beaucoup plus que cela facilement sans un impact sur les performances. –

Répondre

2

L'interface IAsyncResult inclut une propriété AsyncWaitHandle de type WaitHandle. Un WaitHandle consomme des ressources du système d'exploitation.

En fait, WaitHandle implémente l'interface IDisposable, donc la classe implémentant IAsyncResult devrait elle-même implémenter IDisposable.

Ceci est tout dire que des centaines de cas IAsyncResult le mensonge est autour pas un problème mémoire - c'est une question des ressources. Les nouveaux appels de socket éliminent le besoin de placer des centaines d'objets.

1

Un cache sans politique d'expiration est une fuite de mémoire. Il n'y a rien dans votre question qui suggère que vous avez considéré une bonne politique. Si vous n'en avez pas, n'utilisez pas de cache. Si vous le faites, testez-le pour voir si vous pouvez mesurer les améliorations réelles.