在循环中多次调用WCF服务方法(使用相同的代理对象)导致超时

时间:2011-01-07 19:30:01

标签: reporting-services windows-services timeout wcf

我在循环中重复调用WCF服务方法(每次迭代时使用不同的参数),并且在大约40分钟后导致超时。我正在使用相同的代理对象,只有在完成循环后才关闭它。如何避免此超时错误?我是否需要为每个调用实例化一个新代理。 (实际上我在这里调用一个SQL服务器报告服务器webservice并传递不同的参数来生成不同的报告,并且我没有为每次迭代使用新的代理,这可能会减慢报告的生成速度)。这里的客户端也是一个WCF服务,它托管在一个Windows服务中。

(这只是一个示例,而不是失败的实际代码)

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

错误信息是这样的

  

System.TimeoutException:请求   通道在等待时超时   00:01:00后回复。增加   传递给调用的超时值   请求或增加SendTimeout   绑定值。时间   分配给这个操作可能有   是超时的一部分。   ---&GT; System.TimeoutException:HTTP请求   'HTTP://localhost/ReportServer/ReportExecution2005.asmx'   已超过分配的超时时间   00:01:00。分配给此的时间   操作可能是一部分   更长的超时。 ---&GT;   System.Net.WebException:该操作   已经超时了

这是客户端WCF配置(仅与报告服务相关的部分,而不是整个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>

4 个答案:

答案 0 :(得分:2)

此问题现已解决。其中一个报告(通过调用报告服务器ASMX webservice生成)比平时花费更长时间并导致超时,这不是由于循环中的调用次数(每个webservice调用是同步的而没有排队) 。为了解决这个问题,我使用标准的ASP.NET webservice API而不是WCF来调用报告执行webservice,并将超时设置为无限,就像这样

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

超时可能已被设置为更大的值而不是无限。每个报告都会循环调用此Web服务,一次性生成所有用户选择的报告大约需要两个小时。客户端是一个WCF服务,并托管在Windows服务而不是IIS中,以避免客户端超时。感谢所有的回复。

答案 1 :(得分:1)

这仅仅意味着您的服务器无法处理负载,或者由于某些其他原因而耗费太长时间。问问服务器为什么要花太长时间;当客户超时时不要感到惊讶。

答案 2 :(得分:0)

如果您正在从客户端进行异步调用,而服务器不是“webfarm”,则将在服务器上对所有调用进行qued。这可能会使通话超时。它并没有真正说明你的代码。

假设您正在浏览包含10个项目的列表,每个响应需要10秒钟才能在服务器上进行处理。由于您使用的是同一个代理,因此从客户端代码调度的速度非常快。但是返回所有答案大约需要100秒(请注意,我没有考虑到你有网络延迟,对象血清等等) 这意味着nr 6之后的所有调用都将超时。

如果服务器有更多线程可用于处理数据,则可以避免,但问题可能会在其他地方弹出。您应该能够再次尝试相同的呼叫,因为超时也可能由于任何其他原因,网络问题,临时服务器过载等等而出现。

我会制作某种调度系统来调度所有服务器调用,以便您可以再次进行相同的调用。如何实现取决于您的方案: 他们需要按特定顺序发送吗? 您是否需要知道最后一次通话何时返回? 等

答案 3 :(得分:0)

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