2009-12-10 3 views
1

J'ai un service WCF, qui est appelé à partir de mon application Silverlight 3 (avec C#). Le service est appelé pour chaque élément dans une zone de liste remplie par l'utilisateur. Lorsqu'un seul élément est contenu dans la liste, tout fonctionne correctement. Plusieurs éléments provoquent une erreur parfois. J'ai testé un peu autour et parfois je reçois une erreur avec 2 items, parfois non. Avec 4 items test, une fois j'obtiens 2 résultats retournés, après que l'erreur. Le pire, c'est que l'erreur dit simplement "Le Remoteserver a renvoyé une erreur: NotFound". L'erreur est un « CommunicationException » et est jeté dans la EndMethod méthode (résultat System.IAsyncResult)Erreur lors de l'appel rapide du service WCF

Voici l'appel:

foreach (ListBoxItem lbItem in categorySeeds) 
{ 
    Helper.Instance.service.ClusterAsync(Helper.Instance.language.value, 
    ((KeyValuePair<string, int>)lbItem.Tag).Value, 
    Helper.Instance.clusterLevel, 
    Helper.Instance.clusterDelay, 
    Helper.Instance.clusterTolerance, 
    Helper.Instance.clusterMaxCategories, 
    Helper.Instance.similarity); 
} 

Je me souviens que j'ai déjà « résolu » le problème en appelant « réutilisation » de l'AppPool qui contenait mon WCF ... alors peut-être qu'il y a quelque chose qui ne va pas avec la configuration? Est-ce que quelqu'un sait si je peux rendre le WCF retournant un message d'erreur plus significatif que juste "NotFound"?

Merci à l'avance, Frank

RÉPONSE: Le problème a été causé par l'accès simultané des multiples WCF-Service-appels. Le service appelle StoredProcedures qui fonctionne avec un Synonym-Objects que chaque SP change à une valeur donnée par un paramètre ... donc je dois le réparer là.

Répondre

2

Le serveur WCF aura un nombre maximal d'appels simultanés et de sessions simultanées, qui sont respectivement de 10 et 16. Si vous appelez ce service trop rapidement avec plus que ce nombre d'appels, vous risquez d'obtenir des délais d'attente et/ou des messages rejetés.

C'est un comportement de service (serviceThrottling) qui est en effet configurable sur le serveur:

<serviceBehaviors> 
    <behavior name="YourServiceBehavior"> 
     <serviceDebug includeExceptionDetailInFaults="True" /> 
     <serviceThrottling 
      maxConcurrentCalls="25" 
      maxConcurrentInstances="25" 
      maxConcurrentSessions="25"/> 
    </behavior> 
</serviceBehaviors> 

Le message d'erreur générique que vous revenez de WCF est tout à fait exprès - les concepteurs WCF ne voulaient pas révéler quoi que ce soit à un appelant extérieur qui pourrait l'aider à exploiter votre système. Cela aussi peut être modifié par un comportement de service, qui renvoie alors un message d'erreur plus significatif pour vous:

<serviceBehaviors> 
    <behavior name="YourServiceBehavior"> 
     <serviceDebug includeExceptionDetailInFaults="True" /> 
    </behavior> 
</serviceBehaviors> 
+0

Le problème décrit doit être assez commun, sûrement la solution n'est pas de bricoler avec l'étranglement? Le client n'ouvrira pas si facilement autant de connexions au même serveur, il mettrait sûrement en file d'attente de telles demandes sur le client et seulement quelques demandes concurrentes seraient en attente. En outre, l'OP décrit parfois des problèmes avec seulement deux entrées, donc je ne peux pas voir comment le changement d'accélérateur aidera. Je soupçonne que les exceptions détaillées révéleront que le code serveur ne gère pas correctement la simultanéité de plusieurs appels. – AnthonyWJones

+0

Vous avez absolument raison, Anthony. J'avais déjà la propriété serviceDebug en place, mais lors de la consommation d'un WCF avec Silverlight 3, vous devez vous battre un peu plus pour obtenir vraiment l'erreur: http://msdn.microsoft.com/en-us/library/dd470096(VS .96) .aspx - Après avoir mis cela en place, j'ai trouvé que l'erreur est causée par l'accès simultané au SQL-StoredProcedures par le service WCF. J'utilise un synonyme pour interroger différentes tables qui ont la même structure. Mais c'est une autre histoire ... * soupir * – Aaginor

2

Vous devez disposer le service après que vous l'appelez. J'ai eu le même problème et je l'ai fixé en utilisant l'instruction -

using (TempConvertService TMPConSvc = 
new TempConvertService.TempConvertServiceClient()) 
{ 
result = TMPConSvc.ConvertToF(32.00); 
return result; 
} 
Questions connexes