2011-01-07 1 views
1

J'appelle une méthode de service WCF à plusieurs reprises dans une boucle (avec différents paramètres à chaque itération) et elle provoque un délai d'attente après environ 40 minutes. J'utilise le même objet proxy et je le ferme seulement quand la boucle est complétée comme ça. comment puis-je éviter cette erreur de timeout? dois-je instancier un nouveau proxy pour chaque appel. (En fait, j'appelle ici un service web de serveur de reporting SQL server et je passe différents params pour générer différents rapports et je n'utilise pas de nouveau proxy pour chaque itération qui pourrait ralentir la génération de rapports). Voici le client est également un service WCF et il est hébergé dans un service Windows.Plusieurs appels à la méthode de service WCF dans une boucle (utilisant le même objet proxy) provoquant le dépassement

(ce qui est juste un exemple d'illustration, et non le code réel qui échoue)

using(var proxy=new serviceclient()) 
{ 
    for(var i=0;i<50;i++) 
    { 
     proxy.methodName(i); 
    } 
} 

Le message d'erreur est quelque chose comme ça

System.TimeoutException: La chaîne demande chronométré en attendant une réponse après 00:01:00. Augmentez la valeur de délai d'attente transmise à l'appel à Demandez ou augmentez la valeur SendTimeout dans la liaison. Le temps affecté à cette opération peut avoir été une partie d'un délai d'attente plus long. ---> System.TimeoutException: La requête HTTP à 'http: //localhost/ReportServer/ReportExecution2005.asmx' a dépassé le délai imparti de 00:01:00. Le temps alloué à cette opération a peut-être fait partie d'un dépassement de délai plus long de . ---> System.Net.WebException: L'opération a expiré

est ici la configuration WCF client (seule partie qui est liée aux services d'information, et non l'ensemble de configuration WCF)

<bindings> 
    <basicHttpBinding> 
    <binding name="ReportExecutionServiceSoap" closeTimeout="00:01:00" 
     openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" 
     allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" 
     maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" 
     messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" 
     useDefaultWebProxy="true"> 
     <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" 
     maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> 
     <security mode="TransportCredentialOnly"> 
     <transport clientCredentialType="Ntlm" proxyCredentialType="None" 
      realm="" /> 
     <message clientCredentialType="UserName" algorithmSuite="Default" /> 
     </security> 
    </binding> 
    </basicHttpBinding> 
</bindings> 
<client> 
    <endpoint address="http://localhost/ReportServer/ReportExecution2005.asmx" 
    binding="basicHttpBinding" bindingConfiguration="ReportExecutionServiceSoap" 
    contract="ReportExecutionServiceReference.ReportExecutionServiceSoap" 
    name="ReportExecutionServiceSoap" /> 
</client> 

Répondre

2

ce problème est résolu maintenant. l'un des rapports (généré en appelant le serveur Web ASMX) a pris plus de temps que d'habitude et a causé le délai, il n'était PAS dû au nombre d'appels dans la boucle (chaque appel de service web est synchrone et non en file d'attente) . Pour résoudre ce problème, je l'API standard ASP.NET webservice au lieu de WCF pour appeler l'exécution du rapport webservice et définir le délai d'attente à l'infini comme celui-ci

var webServiceProxy = new ReportExecutionServiceReference.ReportExecutionService() 
           { 
            Url = ConfigurationManager.AppSettings["ReportExecutionServiceUrl"], 
            Credentials = System.Net.CredentialCache.DefaultCredentials 
           }; 
    webServiceProxy.Timeout = Timeout.Infinite; 

le délai aurait pu être réglé à une plus grande valeur au lieu d'infini ainsi que. ce webservice est appelé en boucle pour chaque rapport et il faut environ deux heures pour générer tous les rapports sélectionnés par l'utilisateur en une fois. Le client est un service WCF et hébergé dans un service Windows au lieu de IIS pour éviter un délai d'attente sur le client. Merci pour toutes vos réponses.

0

Si vous effectuez des appels asynchrones à partir du client et que le serveur n'est pas une «webfarm», tous les appels seront traités sur le serveur. Et cela pourrait faire des appels timeout. Cela ne dit pas vraiment votre code. Supposons que vous parcourez une liste de 10 éléments, chaque réponse prend 10 secondes à traiter sur le serveur. Puisque vous utilisez le même proxy, tous les appels seront très rapidement envoyés à partir du code client. Mais cela prendra environ 100 secondes pour renvoyer toutes les réponses (notez que je ne prends pas en compte que vous avez la latence de réseau, la sérilisation d'objet etc.) Cela signifie que tous les appels après le nr 6 expireront.

Si le serveur disposait de plus de threads pour traiter les données, cela aurait pu être évité, mais le problème pourrait apparaître ailleurs. Vous devriez être en mesure d'essayer le même appel encore, car un délai d'attente pourrait compenser pour toute autre raison, problème de réseau, surcharge temporaire du serveur, etc

Je voudrais créer une sorte de système quing qui distribue tout le serveur appelle pour que vous puissiez faire le même appel à nouveau. La façon dont cela sera mis en œuvre dépend de votre scénario: Doivent-ils être envoyés dans un ordre spécifique? Avez-vous besoin de savoir quand le dernier appel est retourné? etc.

+0

Ici, chaque appel de méthode est synchrone, de sorte que le client attendra jusqu'à ce que le rapport soit généré, avant de faire une demande pour un autre rapport. maintenant j'essaye d'instancier et de fermer le proxy pour chaque appel et voir si cela fonctionne. Merci pour la réponse – RKP

1

Cela signifie simplement que votre serveur ne peut pas gérer la charge ou prend trop de temps pour une autre raison.Demandez au serveur pourquoi cela prend trop de temps; Ne soyez pas surpris lorsque le client expire.

0
Dim ws As WCFService.ServiceClient = New WCFService.ServiceClient 
ws.Endpoint.Binding.SendTimeout() = TimeSpan.FromSeconds(2) 
Questions connexes