大约10次左右的呼叫后,WCF停止响应(限制)

时间:2009-04-11 01:14:59

标签: c# wcf web-services throttling

我有一个WCF服务和一个带有服务引用的应用程序,并且在应用程序中我有一个循环,并且在每次迭代中它都在调用这个wcf web服务中的方法。

问题是大约9次约会之后,它就会停止......如果你点击VS的Pause按钮,你会看到它停在拨打电话的线路上。

等待一段时间后,抛出 TimeoutException

  

请求频道超时了   等待回复之后   00:00:59.9970000。增加超时   传递给Request或者调用的值   增加了SendTimeout值   捆绑。分配给此的时间   操作可能是一部分   更长的超时。


我对此进行了一些研究,发现了一些涉及在应用程序中编辑app.config的解决方案,以下是摘录:

<serviceBehaviors>
    <behavior name="ThrottlingIssue">
        <serviceThrottling maxConcurrentCalls="500" maxConcurrentSessions="500" />
    </behavior>
</serviceBehaviors>

<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" 
 maxArrayLength="2147483647" 
 maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> 

然后,在我停止调试后,几分钟后,会弹出一条错误消息,告诉我发生了灾难性故障

如何解决此问题?当我使用普通的Web服务时,我没有遇到这个问题。


供参考,这是整个app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <behaviors>
            <serviceBehaviors>
                <behavior name="ThrottlingIssue">
                    <serviceThrottling maxConcurrentCalls="500" maxConcurrentSessions="500" />
                </behavior>
            </serviceBehaviors>
        </behaviors>
        <bindings>
            <wsHttpBinding>
                <binding name="WSHttpBinding_IDBInteractionGateway" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
                    allowCookies="false">
                    <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
                        maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
                    <reliableSession ordered="true" inactivityTimeout="00:10:00"
                        enabled="false" />
                    <security mode="Message">
                        <transport clientCredentialType="Windows" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="Windows" negotiateServiceCredential="true"
                            algorithmSuite="Default" establishSecurityContext="true" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:28918/DBInteractionGateway.svc"
                binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IDBInteractionGateway"
                contract="DBInteraction.IDBInteractionGateway" name="WSHttpBinding_IDBInteractionGateway">
                <identity>
                    <dns value="localhost" />
                </identity>
            </endpoint>
        </client>
    </system.serviceModel>
</configuration>

[更新]解决方案:

显然,在每次请求后你必须Close连接 ...我现在正在关闭每个请求后的连接,它就像魅力一样。

虽然我仍然无法理解的是,在我的app.config中,我将maxConcurrentCalls和maxConcurrentSessions设置为500,然而,我只能制作10.任何人都有任何答案? (也许我在上面发布的app.config中有错误)

上述问题(现在为虚线)的答案是因为我正在编辑客户端app.config,而不是服务配置文件(web.config

6 个答案:

答案 0 :(得分:27)

允许的并发连接的默认数量是10.
很可能你的客户没有关闭连接。

要增加并发呼叫的数量,您必须将您的行为添加到服务配置,而不是客户端。

答案 1 :(得分:3)

对clientservice.close()的调用将解决问题。

答案 2 :(得分:1)

本周我遇到了这个问题而且我无法弄清楚发生了什么。 实际上我确实将我对服务的调用改为Dispose()服务客户端,但它似乎没有任何效果。显然,有一个潜伏在某个地方的服务电话。

有什么值得注意的是让我决定这是问题的原因:此限制与Web服务的实际套接字连接数无关。当您达到maxConcurrentSessions限制时,仍然只有一个实际套接字连接。我用netstat检查了这一点,这让我得出了错误的结论。因此,不要将会话与套接字混淆

我们为所有WCF服务定义了接口,因此我计划在我的代码中调整此模式:

IMyService service = new MyServiceClient();
using (service as IDisposable)
{
    service.MyServiceMethod();
}

有趣的是,当服务(和网站)托管在IIS上时,我没有遇到这个问题。配置(几乎)相同,但我无法在该计算机上重现此行为。我想这是一件好事:)

@ John Saunders(关于using中的变量赋值):

我通常会将变量赋值放在using语句中。但是生成的IMyService不能隐式转换为IDisposable。如果你真的想在那里进行任务,我想替代方案是:

IService service;
using ((service = new ServiceClient()) as IDisposable)
{
}

但仍然存在变量范围错误的问题。对IService service的引用无法使用,但仍在范围内。所以在这方面会更好:

using (IDisposable serviceDisposable = new ServiceClient())
{
     IService service = (IService)serviceDisposable;
}

这要求我引入一个额外的变量名称。的 *咩*

答案 3 :(得分:1)

这可以通过将单例类创建为Web服务引用和应用程序之间的接口来解决。然后它将只创建一个服务引用实例。

class ServiceInterface
{
     private static ServiceInterface  _instance;
     private ServiceClient _service = new ServiceClient ;
     private ServiceInterface()
     {
       //Prevent accessing default constructor
     }

     public static ServiceInterface GetInstance()
     {

     if(_instance == null)

     {

      _instance = new ServiceInterface();

    }

        return _instance;



 }


   // You can add your functions to access web service here

    Public int PerformTask()
    {
         return _service.PerformTask();
    }
}

答案 4 :(得分:0)

你可以configure tracing并运行循环吗?可能是渠道出现故障并导致客户超时。

答案 5 :(得分:0)

将我的头发拉过很多类似的问题后,Close()Dispose()无法解决这个问题,我想添加一个简单的解决方案,即成为我的一天,即通过增加默认为2的ServicePointManager.DefaultConnectionLimit

  

“DefaultConnectionLimit属性设置ServicePointManager对象在创建ServicePoint对象时分配给ConnectionLimit属性的默认最大并发连接数。”

在我的情况下,我的应用程序成功连接到我的远程服务2次,在第三次尝试时它根本没有尝试连接到该服务。相反,它在使用与上述问题相同的错误消息超时前等待一段时间。增加DefaultConnectionLimit解决了这个问题。为了增加挫败感,这种行为有点随机 - 在10个案例中,webservice成功调用多次(> 2次)。

解决方案的起源并进一步讨论了这两个主题:wcf-timeout-exception-detailed-investigationwcf-service-throttling。解决了我的问题。