2009-10-22 7 views
1

J'ai un service WCF avec les paramètres suivants:WCF ConcurrencyMode.Multiple meilleures pratiques de connexion et Caching

  • NetNamedPipeBinding
  • ConcurrencyMode.Multiple
  • InstanceContextMode.Single

maintenant J'ai un client qui accède à ce service WCF d'une manière multi-thread. Dans la mesure où je comprends, je dois ouvrir une nouvelle connexion au service pour chaque thread afin d'éviter que les threads se bloquent les uns les autres.

  • Dans ce cas Quel est le prix Open() appel (service est dans le même ordinateur)?
  • Dois-je mettre en cache/mettre en pool la classe de mon client? (dérivé de ClientBase) ou est-ce que WCF fournit un pool transparent pour les connexions similaires à SQLConnection Pooling?
+0

Pour un tel scénario, communication sur machine NetNamedPipe, je ne vois pas la complexité ajoutée de ConcurrencyMode.Multiple en tant que bénéfice. Cela rend juste votre code de service beaucoup plus complexe et sujet aux erreurs .... Je ne sais pas si cela en vaut la peine et les problèmes de maintenance possibles, comparé à quelques nanosecondes enregistrées dans la création de proxy client ..... –

+1

Sans multiple cela ne fonctionnerait pas comme multithread, cela signifie que le multihtreading dans le client serait inutile puisqu'il attendra les uns les autres. Et ce n'est pas un appel de la milliseconde cela prend quelques secondes. Ou est-ce que je manque quelque chose? –

Répondre

3

Malheureusement, WCF ne regroupe pas les connexions client. J'ai découvert qu'Open() est relativement lent et a construit mes propres mécanismes de pool en gardant une poignée de connexions persistantes ouvertes entre le client et le serveur. Un point commun à ce sujet est que si quelque chose d'aussi simple qu'un time-out se produit entre le client et le serveur (ou toute sorte de CommunicationException est levée), l'instance cliente entre dans un état Faulted et devient inutilisable. A ce moment, vous devez le détruire et le remplacer par une nouvelle instance.

+0

aghh! c'est assez sale. J'ai déjà construit un système de cache, mais je n'aime pas l'idée de complexité supplémentaire. Merci pour la clarification +1. –

+0

Je doute que l'appel Open() soit lent dans un scénario d'appel "sur machine uniquement" avec la liaison NetNamedPipe. Oui, il peut être lent en utilisant wsHttpBinding (la valeur par défaut) qui a beaucoup de surcharge de fonctionnalité WS- * - mais les pipes nommés sont très efficaces, et sur machine seulement, à côté de pas de sécurité - cela ne devrait poser aucun problème. –

+1

Même avec NetNamedPipe, il y a plus de frais généraux que je ne peux supporter. Donnez-lui un tourbillon, sérieusement. Sur mon lappy j'ai vu le temps d'instantion de 150ms à 350ms. J'ai fini par mettre un pub/sous en face d'un répartiteur avec un groupe de clients et j'ai vu une performance assez spectaculaire. –

1

La réponse de James Alexander est sur place (vous devez mettre en commun les connexions vous-même), mais j'ai pensé que je posterais a link to a blog entry qui parle d'une implémentation qui ajoute le pool de connexion à ClientBase. Here's the follow up post où il va dans les détails et fournit un lien pour télécharger le code.

+0

bonnes choses, en particulier l'analyse comparative. Que diriez-vous d'un code? :) J'ai déjà ajouté de la mise en cache mais votre mise en page semble soignée, il serait bon de jeter un coup d'oeil en avant-première :) –

+0

Le blog n'est en réalité pas le mien (je ne veux pas voler de crédit!). Je le sais juste parce que j'ai déjà étudié ce sujet.J'aurais dû vous donner l'autre lien à son poste où il donne en fait plus de détails et de code. Je vais modifier mon entrée. –

+0

ops! Je vois que je pensais que c'était votre blog, de toute façon certainement un bon lien pour prouver le point. –