Service WCF, comment augmenter le délai d'expiration?

93

Cela peut sembler une question idiote, mais tout dans WCF semble beaucoup plus compliqué que dans asmx, comment puis-je augmenter le délai d'expiration d'un service svc?

Voici ce que j'ai jusqu'à présent:

<bindings>
      <basicHttpBinding>
        <binding name="IncreasedTimeout" 
          openTimeout="12:00:00" 
          receiveTimeout="12:00:00" closeTimeout="12:00:00"
          sendTimeout="12:00:00">
        </binding>
      </basicHttpBinding>
</bindings>

Et puis mon point de terminaison est mappé comme ceci:

<endpoint address="" 
  binding="basicHttpBinding" bindingConfiguration="IncreasedTimeout"
             contract="ServiceLibrary.IDownloads">
             <identity>
                <dns value="localhost" />
             </identity>
          </endpoint>

L'erreur exacte que je reçois:

Le canal de demande a expiré en attendant une réponse après 00: 00: 59.9990000. Augmentez la valeur de délai d'expiration transmise à l'appel à Request ou augmentez la valeur SendTimeout sur la liaison. Le temps alloué à cette opération peut avoir été une partie d'un délai d'attente plus long.

Dans le client de test WCF, il existe une icône de configuration qui contient la configuration d'exécution de mon service:

Comme vous pouvez le voir, ce ne sont pas les mêmes valeurs que celles que j'ai définies pour cela? Qu'est-ce que je fais mal?

<bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_IDownloads" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="None">
                        <transport clientCredentialType="None" proxyCredentialType="None"
                            realm="">
                            <extendedProtectionPolicy policyEnforcement="Never" />
                        </transport>
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
JL.
la source

Réponses:

179

Dans votre configuration de liaison, vous pouvez modifier quatre valeurs de délai d'expiration:

<bindings>
  <basicHttpBinding>
    <binding name="IncreasedTimeout"
             sendTimeout="00:25:00">
    </binding>
  </basicHttpBinding>

Le plus important est le sendTimeout, qui indique combien de temps le client attendra une réponse de votre service WCF. Vous pouvez spécifier hours:minutes:secondsdans vos paramètres - dans mon exemple, j'ai défini le délai d'expiration à 25 minutes.

Le openTimeoutcomme son nom l' indique est la quantité de temps que vous êtes prêt à attendre lorsque vous ouvrez la connexion à votre service WCF. De même, lecloseTimeout s'agit de la durée pendant laquelle vous fermez la connexion (supprimez le proxy client) pendant laquelle vous attendez avant qu'une exception soit levée.

C'est receiveTimeoutun peu comme un miroir pour le sendTimeout- alors que le délai d'envoi est le temps que vous attendez une réponse du serveur, receiveTimeoutc'est le temps que vous accorderez au client pour recevoir et traiter la réponse du serveur. serveur.

Dans le cas où vous envoyez des messages "normaux" dans les deux sens, les deux peuvent être assez courts - en particulier receiveTimeout, puisque la réception d'un message SOAP, le déchiffrement, la vérification et la désérialisation ne devraient prendre presque pas de temps. L'histoire est différente avec le streaming - dans ce cas, vous aurez peut-être besoin de plus de temps sur le client pour terminer le "téléchargement" du flux que vous récupérez du serveur.

Il existe également openTimeout, receiveTimeout et closeTimeout. La documentation MSDN sur la liaison vous donne plus d'informations sur leur utilité.

Pour vous familiariser sérieusement avec toutes les subtilités de la WCF, je vous recommande fortement d'acheter le livre " Learning WCF " de Michele Leroux Bustamante:

Apprentissage de WCF http://ecx.images-amazon.com/images/I/51GNuqUJq%2BL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA240_SH20_OU01_.jpg

et vous passez également du temps à regarder sa série de screencast " WCF Top to Bottom " en 15 parties - hautement recommandée!

Pour des sujets plus avancés, je vous recommande de consulter le livre de Juwal Lowy Programming WCF Services.

Programmation WCF http://ecx.images-amazon.com/images/I/41odWcLoGAL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA240_SH20_OU01_.jpg

marc_s
la source
J'ai essayé d'ajouter les sections de liaison à <system.serviceModel> dans web.config, mais cela lance une erreur maintenant .... toutes les étapes supplémentaires que j'ai manquées ...
JL.
J'ai également changé le point de terminaison de mon service en <endpoint address = "" binding = "IncreasedTimeout" - est-ce la mauvaise chose à faire?
JL.
Je pense que je comprends - binding = "basicHttpBinding" bindingConfiguration = "IncreasedTimeout"
JL.
exactement - la liaison est le type de protocole que vous utilisez - basicHttp, wsHttp, netTcp. La configuration de liaison est cette configuration que vous créez dans config pour modifier les délais d'attente, etc.
marc_s
Drôle même après avoir fait cela, toujours une erreur de timeout, Marc pouvez-vous s'il vous plaît donner autant d'informations que possible?
JL.
27

Le meilleur moyen est de modifier les paramètres souhaités dans votre code.

Consultez l'exemple ci-dessous:

using(WCFServiceClient client = new WCFServiceClient ())
{ 
    client.Endpoint.Binding.SendTimeout = new TimeSpan(0, 1, 30);
}
user3891644
la source
c'est une meilleure solution plutôt que de mettre à jour la configuration afin que je puisse configurer une valeur différente pour différents appels et services, merci beaucoup
Salim
26

La configuration du délai d'expiration doit être définie au niveau du client, donc la configuration que je définissais dans le web.config n'avait aucun effet, l'outil de test WCF a sa propre configuration et vous devez définir le délai d'expiration.

JL.
la source
1
eh bien, oui - en général, il doit être défini à la fois sur le client et le serveur, même - par exemple en cas de "inactivityTimeout" sur des sessions et des choses comme ça.
marc_s
8
JL: pouvez-vous montrer exactement ce que vous avez fait? J'ai le même problème
Nick Kahn
Si vous utilisez le «client de test WCF», faites un clic droit sur «Fichier de configuration» dans l'arborescence des services, puis cliquez sur «Modifier avec SvcConfigEditor» et modifiez le délai d'expiration dans les liaisons.
Radderz
4

J'ai récemment eu la même erreur, mais j'ai pu la corriger en veillant à fermer chaque appel client wcf. par exemple.

WCFServiceClient client = new WCFServiceClient ();
//More codes here
// Always close the client.
client.Close();

ou

using(WCFServiceClient client = new WCFServiceClient ())
{ 
    //More codes here 
}
Arjaye
la source
10
N'utilisez pas l'approche `` en utilisant '': omaralzabir.com/do-not-use-using-in-wcf-client
Alex Marshall
Dans les commentaires de omaralzabir.com/do-not-use-using-in-wcf-client , il existe des exemples de la façon de continuer à utiliser usingtout en ne supprimant pas un objet de canal défectueux. Voici un autre blogueur avec une approche plus compatible avec les usingblocs: erwyn.bloggingabout.net/2006/12/09/WCF-Service-Proxy-Helper .
Greg