WCF 在大约 10 次左右调用后停止响应(限制)
Posted
技术标签:
【中文标题】WCF 在大约 10 次左右调用后停止响应(限制)【英文标题】:WCF stops responding after about 10 or so calls (throttling) 【发布时间】:2010-10-18 20:48:19 【问题描述】:我有一个 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
)
【问题讨论】:
过去两天一直在努力解决这个问题,谢谢! 希望我能多次支持这个问题。 我处于完全相同的情况...无法帮助您的帖子解决我的问题,您能看看这个问题吗? ***.com/questions/10305671/… 【参考方案1】:允许的默认并发连接数为 10。 您的客户端很可能没有关闭连接。
要增加并发调用的数量,您必须将行为添加到服务配置,而不是客户端。
【讨论】:
在我的 app.config 中,我将 maxConcurrentCalls 和 maxConcurrentSessions 设置为 500,但我只能设置 10。我的 app.config 有什么问题吗? 您是否在服务元素上设置了 serviceBehavior 以使用行为配置。 看起来您发布了客户端 app.config ? - 您需要更改服务配置.. 但是我的 WCF 项目中没有 app.config 文件。应该有吗? 允许的并发连接是不够的。他仍然需要关闭连接。【参考方案2】:调用 clientservice.close() 将解决问题。
【讨论】:
是的,这就是我在解决方案 [更新] 中提到的问题。【参考方案3】:这周我遇到了这个问题,我无法完全弄清楚发生了什么。
实际上,我确实将对服务的调用更改为服务客户端 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;
这需要我引入一个额外的变量名。 *嗯*
【讨论】:
为什么不把赋值也放到 using 块中呢? 另见iserviceoriented.com/blog/post/Indisposable+-+WCF+Gotcha+1.aspx。 我通常这样做,但using (IMyService service = new MyServiceClient())
不起作用(在 using 语句中使用的类型必须隐式转换为 'System.IDisposable')。在using
中进行分配和强制转换对我来说似乎有点混乱。
那篇文章中的委托解决方案有点优雅,但我不确定我上面的代码 sn-p 是否需要这样的解决方案。除非您的应用死机,否则执行在这两行之间不太可能中断?
using (var service = new ServiceClient())
【参考方案4】:
这可以通过创建单例类作为 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();
【讨论】:
在每个请求上创建一个客户端比保持单例更健壮。我试过这个方法,如果客户端出现故障(即Status == Fault),那么新的请求就会失败。【参考方案5】:你能configure tracing 运行循环吗?可能是通道出现故障导致客户端超时。
【讨论】:
【参考方案6】:在解决了Close()
或Dispose()
都没有解决的很多 类似问题之后,我想添加一个简单的解决方案,让我很开心,即增加@ 987654321@,默认为 2。
“DefaultConnectionLimit 属性设置 ServicePointManager 对象在创建 ServicePoint 对象时分配给 ConnectionLimit 属性的默认最大并发连接数。”
在我的情况下,我的应用程序成功连接到我的远程服务 2 次,在第三次尝试时它根本没有尝试连接到该服务。相反,它在超时之前等待了一段时间,并出现与上述问题相同的错误消息。增加DefaultConnectionLimit
解决了这个问题。更令人沮丧的是,这种行为有点随机 - 在 10 次的情况下,Web 服务被成功调用了多次 (>2) 次。
解决方案源于这两个线程并进一步讨论:wcf-timeout-exception-detailed-investigation 和wcf-service-throttling。解决了我的问题。
【讨论】:
以上是关于WCF 在大约 10 次左右调用后停止响应(限制)的主要内容,如果未能解决你的问题,请参考以下文章