Résumé: je crois que la meilleure pratique consiste à instancier votre client de service web lorsque vous êtes sur le point de l'utiliser, puis le laisser aller hors de portée et obtenir des ordures collectées. Cela se reflète dans les échantillons de venir vous voir à partir de Microsoft. Justification suit...
Complet:La meilleure description complète du processus que j'ai trouvé est au Comment: Accéder à un Service de Silverlight. Ici, l'exemple montre le schéma typique de l'instanciation de la client de service web et permettant d'aller hors de portée (sans avoir besoin de le fermer). Des clients de services Web hériter de ClientBase qui a une méthode Finalize qui doit libérer toutes les ressources non managées, si nécessaire, lorsque l'objet est d'ordures collectées.
J'ai une quantité décente de l'expérience à l'aide de services web, et j'ai utiliser des proxys et les instancier droit avant de l'utiliser, puis de leur permettre d'être nettoyée. Je n'ai jamais eu un problème avec cette approche. J'ai lu sur Wenlong Dong Blog qui a dit que la création de la procuration était cher, mais encore, dit-il de la performance s'est améliorée .NET 3.5 (peut-être qu'il s'est encore amélioré depuis?). Ce que je peux vous dire est que la performance est un terme relatif, et à moins que vos données soient récupérées est moins trivial de taille, beaucoup plus de temps sera consacré à la sérialisation/désérialisation et des transports que la création de la connexion. Cela a certainement été mon expérience, et vous êtes mieux de l'optimisation dans ces domaines.
Dernier, depuis que j'ai la figure de mes opinions à ce jour est peut-être insuffisant, j'ai écrit un test rapide. J'ai créé un Silverlight web service en utilisant le gabarit fourni avec Visual Web Developer 2010 Express (avec, par défaut, une méthode void appelés DoWork()
). Ensuite, dans mon exemple de client Silverlight je l'ai appelé en utilisant le code suivant:
int counter=0;
public void Test()
{
ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
client.DoWorkCompleted += (obj, args) =>
{
counter++;
if (counter > 9999)
{
for(int j=0;j<10;j++) GC.Collect();
System.Windows.MessageBox.Show("Completed");
}
};
client.DoWorkAsync();
}
J'ai alors appelé la méthode de Test à l'aide de for(int i=0;i<10000;i++) Test();
et tiré de l'application. Il a fallu un peu plus de 20 secondes pour charger l'application et remplissez les appels de service web (tous les 10 000 d'entre eux). Comme le service web d'appels ont été faits, j'ai vu l'utilisation de la mémoire pour le processus de sauter à plus de 150 MO, mais une fois que les appels réalisés et GC.Collect()
a été appelé l'utilisation de la mémoire est tombé à moins de la moitié de cette somme. Loin d'être un parfait test il me semble me confirmer qu'aucune mémoire ne fuyait, ou il a été négligeable (en considérant qu'il est sans doute assez rare, à l'appel de 10 000 appels de service web tout en utilisant séparer les instances de client). Aussi c'est un modèle plus simple que de garder un objet proxy et avoir à vous soucier de failles et d'avoir à les rouvrir.
La Justification de la Méthodologie de l'Essai:
Mon test axé sur les 2 problèmes potentiels. L'un est une fuite de mémoire, et l'autre est le processeur le temps passé à créer et à détruire les objets. Ma recommandation est qu'il est sûr de suivre les exemples fournis par la société (Microsoft) qui fournit les classes. Si vous êtes préoccupé par l'efficacité du réseau, alors vous devriez avoir aucun problème avec mon exemple dans la mesure correctement la création/l'élimination de ces objets ne serait pas l'effet de la latence du réseau. Si 99% du temps passé est l'heure du réseau, puis optimisation pour l'un théorique, l'amélioration dans le 1% est probablement un gaspillage en termes de temps de développement(en supposant qu'il est même un avantage à gagner qui, je crois, mon test montre clairement qu'il y a peu/aucun). Oui, la mise en réseau des appels locaux c'est à dire qu'au cours des 10 000 appels de service, seulement environ 20 secondes sera passé à attendre pour les objets. Qui représente environ 2 millisecondes par appel de service consacré à la création de ces objets. Quant à la nécessité de Disposer d'appel, je ne veux pas laisser entendre que vous ne devriez pas l'appeler, mais simplement qu'il ne semble pas nécessaire. Si vous oubliez (ou tout simplement choisir de ne pas), mes tests m'ont amené à croire que d'Aliéner a été appelé dans le Finaliser pour ces objets. De même, il serait probablement plus efficace d'appeler Disposer vous-même, mais encore l'effet est négligeable. Pour la plupart des logiciels de développement, vous obtenez plus de gains de venir avec plus d'efficacité des algorithmes et structures de données que par languir plus de ces questions (sauf si il y a une grave fuite de mémoire). Si vous avez besoin de plus d'efficacité, alors peut-être vous ne devriez pas être en utilisant les services web comme il y a plus efficace des données options de transport en commun qu'un système qui est basé sur XML.