Увеличение таймаута для веб-службы WCF в С#

В настоящее время у меня есть приложение, которое вызывает веб-службу на сервере для поиска. Мы можем ожидать, что большой объем данных будет возвращен, поэтому поиск займет больше минуты, является обычным делом.

Мы получили следующее сообщение об ошибке для таких запросов большого объема:

Время ожидания ответа на запрос после 00: 00: 59.7350618. Увеличьте значение тайм-аута, переданного вызову Запросить или увеличьте значение SendTimeout в Binding. Время, отведенное для этой операции, возможно, было частью более длительного таймаута.

Это то, что мы видели в нескольких вопросах, уже опубликованных в StackOverflow, к сожалению, ни одно из доступных решений не помогло мне устранить проблему или даже настроить тайм-аут.

Мы оба изменили app.config для клиента, увеличили все таймауты там (CloseTimeout, OpenTimeout, ReceiveTimeout и SendTimeout) и все значения web.config для службы на сервере (closeTimeout, openTimeout и SendTimeout).

Ни одно из этих изменений не повлияло, я все равно получаю минутный тайм-аут. Любая идея, почему изменения этих значений не будут иметь эффекта?

В приведенных ниже примерах мы снизили время, чтобы не дождаться полной минуты во время тестирования.

Web.config:

<configuration>
  <system.web>
    <compilation targetFramework="4.0" />
  </system.web>
  <system.diagnostics>
    <trace autoflush="true" />
    <sources>
      <source name="System.Net">
        <listeners>
          <add name="TraceFile" />
        </listeners>
      </source>
      <source name="System.Net.Sockets">
        <listeners>
          <add name="TraceFile" />
        </listeners>
      </source>
    </sources>
    <sharedListeners>
      <add name="TraceFile" type="System.Diagnostics.TextWriterTraceListener"
           initializeData="trace.log" />
    </sharedListeners>
    <switches>
      <add name="System.Net" value="Verbose" />
      <add name="System.Net.Sockets" value="Verbose" />
    </switches>
  </system.diagnostics>
  <system.serviceModel>
    <diagnostics>
      <messageLogging logMalformedMessages="false" logMessagesAtServiceLevel="false"
                      logMessagesAtTransportLevel="false" />
    </diagnostics>
    <services>
      <service behaviorConfiguration="SearchIndexServiceBehavior" name="SearchIndex.Service">
        <endpoint address="" binding="basicHttpBinding" contract="ISearchIndexServices" />
        <host>
          <timeouts closeTimeout="00:00:10" />
        </host>
      </service>
    </services>
    <bindings>
      <basicHttpBinding>
        <binding closeTimeout="00:00:10" openTimeout="00:00:15" sendTimeout="00:00:20"
                 receiveTimeout="00:00:25" maxBufferSize="2147483647" maxBufferPoolSize="2147483647"
                 maxReceivedMessageSize="2147483647">
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
                        maxArrayLength="2147483647" maxBytesPerRead="2147483647"
                        maxNameTableCharCount="2147483647" />
        </binding>
      </basicHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior name="SearchIndexServiceBehavior">
          <serviceMetadata httpGetEnabled="false" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  <system.transactions>
    <defaultSettings timeout="00:05:00" />
  </system.transactions>
</configuration>

app.config

<configuration>
  <configSections>
  </configSections>
  <startup>
  </startup>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_ISearchIndexServices" closeTimeout="00:00:10" openTimeout="00:00:15" receiveTimeout="00:10:00" sendTimeout="00:00:20" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="5242880" maxBufferPoolSize="524288" maxReceivedMessageSize="5242880" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true"> 
          <readerQuotas maxDepth="32" maxStringContentLength="5242880"maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://MyServer/SearchIndexService/SearchIndexServices.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ISearchIndexServices" contract="WFC.ISearchIndexServices" name="BasicHttpBinding_ISearchIndexServices" />
    </client>
  </system.serviceModel>
</configuration>

Ответ 1

Я думаю, что вы, вероятно, нажимаете OperationTimeout для канала запроса на стороне клиента, который по какой-то причине не легко настраивается с помощью стандартных атрибутов конфигурации.

Попробуйте выполнить это в клиентском коде перед вызовом долговременной операции:

((IContextChannel)clientProxy.InnerChannel).OperationTimeout = new TimeSpan(0,30,0); // For 30 minute timeout - adjust as necessary

где clientProxy - это экземпляр класса клиента, созданного с помощью служебной ссылки (который получен из ClientBase<ISearchIndexService>).

Ответ 2

В этом примере модели сервиса показаны свойства тайм-аута элемента привязки, которые необходимо установить в клиенте web.config.

Обратите внимание, что для всех параметров таймаута установлено значение 10 минут. В этом примере используется элемент привязка конфигурации, чтобы установить свойство "maxItemsInObjectGraph" . Обычно, если вам нужно отключить тайм-аут, это означает, что вы, вероятно, переносите большие объемы данных. Обратите внимание также, что размеры данных, подлежащих передаче, все настроены на обработку до 2 гигабайт.

<?xml version="1.0" encoding="UTF-8"?>
<system.serviceModel>
   <bindings>
      <basicHttpBinding>
         <binding name="BasicHttpBinding_ISearchIndexServices" closeTimeout="00:10:00" openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10: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="None">
               <transport clientCredentialType="None" proxyCredentialType="None" realm="" />
               <message clientCredentialType="UserName" algorithmSuite="Default" />
            </security>
         </binding>
      </basicHttpBinding>
   </bindings>
   <client>
      <endpoint address="http://MyServer/SearchIndexService/SearchIndexServices.svc" behaviorConfiguration="SearchIndexServicesBehavior" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ISearchIndexServices" contract="WFC.ISearchIndexServices" name="BasicHttpBinding_ISearchIndexServices" />
   </client>
   <behaviors>
      <endpointBehaviors>
         <behavior name="SearchIndexServicesBehavior">
            <dataContractSerializer maxItemsInObjectGraph="2147483647" />
         </behavior>
      </endpointBehaviors>
   </behaviors>
</system.serviceModel>

Ответ 3

Вы можете попробовать это

 SeriveClient client=new ServiceClient();
    var time = new TimeSpan(0, 3, 0);
    client.Endpoint.Binding.CloseTimeout = time;
                client.Endpoint.Binding.OpenTimeout = time;
                client.Endpoint.Binding.ReceiveTimeout = time;
                client.Endpoint.Binding.SendTimeout = time;

Ответ 4

Тайм-аут - это время ожидания отправки на клиенте. Это то, как долго клиент готов ждать ответа и поэтому должен быть установлен на клиенте, а не на службе

Ответ 5

Тайм-ауты - это боль при отладке. Кто может отладить менее чем за минуту! Я использовал Junior M/BuzzWilder сверху и добавил следующее к служебному вызову в app.config:

            <binding name="WSHttpBinding_bindingname"
                     openTimeout="01:00:00"
                     closeTimeout="01:00:00"
                     receiveTimeout="01:00:00"
                     sendTimeout="01:00:00"
                     >

Прощай, сервисные тайм-ауты. :)