Servizio WCF, come aumentare il timeout?


93

Potrebbe sembrare una domanda sciocca, ma tutto in WCF sembra molto più complicato che in asmx, come posso aumentare il timeout di un servizio svc?

Ecco cosa ho finora:

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

E poi il mio endpoint viene mappato in questo modo:

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

L'errore esatto che ricevo:

Il canale di richiesta è scaduto durante l'attesa di una risposta dopo 00: 00: 59.9990000. Aumentare il valore di timeout passato alla chiamata a Request o aumentare il valore SendTimeout in Binding. Il tempo assegnato a questa operazione potrebbe essere stato una parte di un timeout più lungo.

Nel client di prova WCF, è presente un'icona di configurazione che contiene la configurazione di runtime del mio servizio:

Come puoi vedere non sono gli stessi valori che ho impostato per esso? Che cosa sto facendo di sbagliato?

<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>

Risposte:


179

Nella configurazione dell'associazione, ci sono quattro valori di timeout che puoi modificare:

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

Il più importante è il sendTimeout, che indica per quanto tempo il client attenderà una risposta dal tuo servizio WCF. Puoi specificare hours:minutes:secondsnelle tue impostazioni: nel mio esempio, ho impostato il timeout a 25 minuti.

Il openTimeoutcome suggerisce il nome è la quantità di tempo che sei disposto ad attendere quando apri la connessione al tuo servizio WCF. Allo stesso modo, closeTimeoutè la quantità di tempo in cui si chiude la connessione (si elimina il proxy client) che si attende prima che venga generata un'eccezione.

Il receiveTimeoutè un po 'come uno specchio per il sendTimeout- mentre il timeout di invio è la quantità di tempo si attendere una risposta dal server, l' receiveTimeoutè la quantità di tempo che ti do client per ricevere ed elaborare la risposta dal server.

Nel caso in cui si inviino messaggi "normali" avanti e indietro, entrambi possono essere piuttosto brevi, in particolare receiveTimeout, poiché la ricezione di un messaggio SOAP, la decrittografia, il controllo e la deserializzazione non dovrebbe richiedere quasi tempo. La storia è diversa con lo streaming: in tal caso, potresti aver bisogno di più tempo sul client per completare effettivamente il "download" dello streaming che torni dal server.

Ci sono anche openTimeout, receiveTimeout e closeTimeout. La documentazione MSDN sull'associazione fornisce ulteriori informazioni a cosa servono.

Per avere una presa seria su tutte le complessità di WCF, ti consiglio vivamente di acquistare il libro " Learning WCF " di Michele Leroux Bustamante:

Imparare 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

e passi anche un po 'di tempo a guardare la sua serie di screencast " WCF dall'alto verso il basso " in 15 parti - altamente raccomandato!

Per argomenti più avanzati ti consiglio di consultare il libro Programming WCF Services di Juwal Lowy .

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


Ho provato ad aggiungere le sezioni di associazione a <system.serviceModel> in web.config, ma ora genera un errore .... eventuali passaggi aggiuntivi che mi sono perso ...
JL.

Ho anche cambiato l'endpoint nel mio servizio in <endpoint address = "" binding = "AumentedTimeout" - è la cosa sbagliata da fare?
JL.

Penso di aver capito - binding = "basicHttpBinding" bindingConfiguration = "AumentedTimeout"
JL.

esattamente - l'associazione è il tipo di protocollo che usi: basicHttp, wsHttp, netTcp. La configurazione del binding è questa configurazione che crei in config per modificare i timeout ecc.
marc_s

Divertente anche dopo averlo fatto, ottenendo ancora un errore di timeout, Marc puoi fornire quante più informazioni possibili?
JL.

27

Il modo migliore è modificare qualsiasi impostazione desiderata nel codice.

Dai un'occhiata all'esempio seguente:

using(WCFServiceClient client = new WCFServiceClient ())
{ 
    client.Endpoint.Binding.SendTimeout = new TimeSpan(0, 1, 30);
}

questa è una soluzione migliore piuttosto che aggiornare la configurazione in modo da poter configurare un valore diverso per chiamate e servizi diversi, molte grazie
Salim

26

La configurazione del timeout deve essere impostata a livello di client, quindi la configurazione che stavo impostando in web.config non ha avuto effetto, lo strumento di test WCF ha una propria configurazione ed è qui che è necessario impostare il timeout.


1
beh, sì - in genere, deve essere impostato sia sul client che sul server, anche - ad esempio in caso di "inactivityTimeout" su sessioni e cose del genere.
marc_s

8
JL: puoi mostrare esattamente cosa hai fatto? Sto avendo lo stesso problema
Nick Kahn

Se si utilizza il "WCF Test Client", fare clic con il pulsante destro del mouse su "File di configurazione" nella struttura dei servizi, quindi fare clic su "Modifica con SvcConfigEditor" e modificare il timeout all'interno dei collegamenti.
Radderz

4

Recentemente ho ricevuto lo stesso errore ma è stato in grado di risolverlo assicurandosi di chiudere ogni chiamata del client wcf. per esempio.

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

o

using(WCFServiceClient client = new WCFServiceClient ())
{ 
    //More codes here 
}

10
Non utilizzare l'approccio "using": omaralzabir.com/do-not-use-using-in-wcf-client
Alex Marshall

Nei commenti di omaralzabir.com/do-not-use-using-in-wcf-client , ci sono esempi di come utilizzare ancora usingsenza eliminare un oggetto canale in errore. Ecco un altro blogger con un approccio più compatibile con i usingblocchi: erwyn.bloggingabout.net/2006/12/09/WCF-Service-Proxy-Helper .
Greg
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.