40

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

问题是在大约 9 次调用之后,它就停止了……如果你Pause按下 VS 的按钮,你会看到它卡在它发出调用的线路上。

在等待一段时间后,会抛出这个TimeoutException :

请求通道在 00:00:59.9970000 之后等待回复时超时。增加传递给 Request 调用的超时值或增加 Binding 上的 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

4

6 回答 6

27

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

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

于 2009-04-11T02:00:08.853 回答
3

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

于 2011-08-02T15:43:31.217 回答
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;
}

不过,这需要我引入一个额外的变量名。*嗯*

于 2009-08-05T18:29:50.337 回答
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();
    }
}
于 2010-06-25T15:39:02.827 回答
0

您可以配置跟踪并运行循环吗?可能是通道出现故障并导致客户端超时。

于 2009-04-11T01:49:52.013 回答
0

在把我的头发拉到一个非常相似的问题上之后,Close()或者Dispose()我想添加一个简单的解决方案让我很开心,即增加ServicePointManager.DefaultConnectionLimit默认情况下的 2。

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

在我的情况下,我的应用程序成功连接到我的远程服务 2 次,在第三次尝试时它根本没有尝试连接到该服务。相反,它在超时之前等待了一段时间,并出现与上述问题相同的错误消息。增加DefaultConnectionLimit解决了这个问题。更令人沮丧的是,这种行为在某种程度上是随机的——在 10 次的情况下,Web 服务被成功调用了多次(>2 次)。

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

于 2011-08-18T20:16:21.547 回答