WCF Service, wie kann man das Timeout erhöhen?

93

Könnte wie eine dumme Frage erscheinen, aber alles in WCF scheint viel komplizierter als in asmx. Wie kann ich das Timeout eines SVC-Dienstes erhöhen?

Folgendes habe ich bisher:

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

Und dann wird mein Endpunkt folgendermaßen zugeordnet:

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

Der genaue Fehler, den ich bekomme:

Der Anforderungskanal ist abgelaufen, während auf eine Antwort nach 00: 00: 59.9990000 gewartet wurde. Erhöhen Sie den Timeout-Wert, der an den Aufruf von Request übergeben wird, oder erhöhen Sie den SendTimeout-Wert in der Bindung. Die diesem Vorgang zugewiesene Zeit war möglicherweise Teil eines längeren Zeitlimits.

Im WCF-Testclient gibt es ein Konfigurationssymbol, das die Laufzeitkonfiguration meines Dienstes enthält:

Wie Sie sehen, sind es nicht die gleichen Werte, die ich dafür festgelegt habe? Was mache ich falsch?

<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>
J L.
quelle

Antworten:

178

In Ihrer Bindungskonfiguration gibt es vier Timeout-Werte, die Sie anpassen können:

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

Das wichtigste ist das sendTimeout, das angibt, wie lange der Client auf eine Antwort von Ihrem WCF-Dienst warten wird. Sie können angebenhours:minutes:seconds in Ihren Einstellungen In meinem Beispiel habe ich das Zeitlimit auf 25 Minuten festgelegt.

Die openTimeoutwie der Name schon sagt ist die Menge an Zeit , die Sie bereit sind zu warten , wenn Sie die Verbindung zu Ihrem WCF - Dienst öffnen. In ähnlicher Weise closeTimeoutist dies die Zeitspanne, die Sie warten, bevor eine Ausnahme ausgelöst wird, wenn Sie die Verbindung schließen (den Client-Proxy entsorgen).

Das receiveTimeoutist ein bisschen wie ein Spiegel für das sendTimeout- während das Sendezeitlimit die Zeit ist, die Sie auf eine Antwort vom Server warten, receiveTimeoutist dies die Zeit, die Sie Ihrem Client geben, um die Antwort vom zu empfangen und zu verarbeiten Server.

Wenn Sie "normale" Nachrichten hin und her senden, können beide ziemlich kurz sein - insbesondere receiveTimeout, da das Entschlüsseln, Überprüfen und Deserialisieren einer SOAP-Nachricht fast keine Zeit in Anspruch nehmen sollte. Beim Streaming sieht die Geschichte anders aus. In diesem Fall benötigen Sie möglicherweise mehr Zeit auf dem Client, um den "Download" des Streams, den Sie vom Server zurückerhalten, tatsächlich abzuschließen.

Es gibt auch openTimeout, receiveTimeout und closeTimeout. In den MSDN-Dokumenten zum Binden finden Sie weitere Informationen dazu.

Um alle Feinheiten von WCF ernsthaft in den Griff zu bekommen, würde ich Ihnen dringend empfehlen, das Buch " Learning WCF " von Michele Leroux Bustamante zu kaufen :

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

und Sie verbringen auch einige Zeit damit, ihre 15-teilige Screencast-Serie " WCF Top to Bottom " anzusehen - sehr zu empfehlen!

Für weiterführende Themen empfehle ich Ihnen, das Buch " Programming WCF Services" von Juwal Lowy zu lesen .

Programmieren von 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
quelle
Ich habe versucht, die Bindungsabschnitte zu <system.serviceModel> in web.config hinzuzufügen, aber es wird jetzt ein Fehler ausgegeben ... alle zusätzlichen Schritte, die ich verpasst habe ...
JL.
Ich habe auch den Endpunkt in meinem Dienst in <endpoint address = "" binding = "Erhöhtes Zeitlimit" geändert. Ist dies das Falsche?
JL.
Ich glaube ich verstehe es - binding = "basicHttpBinding" bindingConfiguration = "Erhöhtes Zeitlimit"
JL.
genau - die Bindung ist die Art des Protokolls, das Sie verwenden - basicHttp, wsHttp, netTcp. Die Bindungskonfiguration wird diese Konfiguration Sie in Config erstellen zu ändern Timeouts usw.
marc_s
Witzig, auch wenn dies immer noch ein Timeout-Fehler ist. Marc, kannst du bitte so viele Informationen wie möglich geben?
JL.
27

Am besten ändern Sie die gewünschten Einstellungen in Ihrem Code.

Schauen Sie sich das folgende Beispiel an:

using(WCFServiceClient client = new WCFServiceClient ())
{ 
    client.Endpoint.Binding.SendTimeout = new TimeSpan(0, 1, 30);
}
user3891644
quelle
Dies ist eine bessere Lösung, als die Konfiguration zu aktualisieren, damit ich einen anderen Wert für verschiedene Anrufe und Dienste konfigurieren kann. Vielen Dank
Salim
26

Die Timeout-Konfiguration muss auf Client-Ebene festgelegt werden, sodass die Konfiguration, die ich in der web.config festgelegt habe, keine Auswirkungen hatte. Das WCF-Testtool verfügt über eine eigene Konfiguration und dort müssen Sie das Timeout festlegen.

J L.
quelle
1
Ja, normalerweise muss es sowohl auf dem Client als auch auf dem Server eingestellt werden, z. B. im Fall von "inactivityTimeout" in Sitzungen und ähnlichen Situationen.
marc_s
8
JL: Können Sie zeigen, was genau Sie getan haben? Ich habe das gleiche Problem
Nick Kahn
Wenn Sie den 'WCF-Testclient' verwenden, klicken Sie in der Dienststruktur mit der rechten Maustaste auf 'Konfigurationsdatei', klicken Sie dann auf 'Mit SvcConfigEditor bearbeiten' und ändern Sie das Zeitlimit innerhalb der Bindungen.
Radderz
4

Ich habe kürzlich den gleichen Fehler erhalten, konnte ihn jedoch beheben, indem sichergestellt wurde, dass jeder wcf-Client-Aufruf geschlossen wurde. z.B.

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

oder

using(WCFServiceClient client = new WCFServiceClient ())
{ 
    //More codes here 
}
Arjaye
quelle
10
Verwenden Sie nicht den "using" -Ansatz: omaralzabir.com/do-not-use-using-in-wcf-client
Alex Marshall
In den Kommentaren von omaralzabir.com/do-not-use-using-in-wcf-client finden Sie Beispiele für die Verwendung, usingohne ein fehlerhaftes Kanalobjekt zu entsorgen. Hier ist ein weiterer Blogger mit einem Ansatz, der besser mit usingBlöcken kompatibel ist : erwyn.bloggingabout.net/2006/12/09/WCF-Service-Proxy-Helper .
Greg