C# WCF 在大约 10 个左右的调用后停止响应(节流)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/739312/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WCF stops responding after about 10 or so calls (throttling)
提问by Andreas Grech
I have a WCF Service and an application with a Service Reference to it, and with the application I have a loop and in each iteration it's making a call to a method in this wcf web-service.
我有一个 WCF 服务和一个带有服务引用的应用程序,我有一个循环,在每次迭代中它都会调用这个 wcf web 服务中的方法。
The problem is that after about 9 calls or so, it just stops...and if you hit Pause
button of VS, you will see that it's stuck on the line where it makes the call.
问题是,在大约 9 次呼叫后,它只是停止了……如果您Pause
按下 VS 按钮,您会看到它卡在发出呼叫的线路上。
After some time waiting for it, this TimeoutExceptionis thrown:
经过一段时间的等待,这个TimeoutException被抛出:
The request channel timed out while waiting for a reply after 00:00:59.9970000. Increase the timeout value passed to the call to Request or increase the SendTimeout value on the Binding. The time allotted to this operation may have been a portion of a longer timeout.
请求通道在 00:00:59.9970000 之后等待回复时超时。增加传递给 Request 调用的超时值或增加 Binding 上的 SendTimeout 值。分配给此操作的时间可能是较长超时的一部分。
I researched a bit on this, and found some solutions that involved editing the app.config in the application, and here are excerpts of it:
我对此进行了一些研究,并找到了一些涉及在应用程序中编辑 app.config 的解决方案,以下是它的摘录:
<serviceBehaviors>
<behavior name="ThrottlingIssue">
<serviceThrottling maxConcurrentCalls="500" maxConcurrentSessions="500" />
</behavior>
</serviceBehaviors>
.
.
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
Then, after I stop debugging, after a couple of minutes, an error message pops up telling me that a Catastrophic failurehas occurred.
然后,在我停止调试后,几分钟后,会弹出一条错误消息,告诉我发生了灾难性故障。
How can I fix this problem? I did not have this issue when I was working with a normal Web Service.
我该如何解决这个问题?当我使用普通的 Web 服务时,我没有遇到这个问题。
For reference, here is the whole app.config
:
作为参考,这里是整个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>
[Update] Solution:
[更新] 解决方法:
Apparently, after each request you have to Close
the connection...I am now closing the connection after each request and it's working like a charm.
显然,在每个请求之后你都必须Close
连接......我现在在每个请求之后关闭连接,它就像一个魅力。
Although what I still can't understand is that in my app.config, I set my maxConcurrentCalls and maxConcurrentSessions to 500, and yet, I can only make 10. Anyone has any answer for that one? (maybe I have something wrong in my app.config posted above)
虽然我仍然无法理解的是,在我的 app.config 中,我将 maxConcurrentCalls 和 maxConcurrentSessions 设置为 500,但我只能制作 10。有人对此有任何答案吗?(也许我上面发布的 app.config 有问题)
The answer for the above question (now dashed) is because I was editing the client app.config
, not the service config file (web.config
)
上述问题的答案(现在是虚线)是因为我正在编辑客户端app.config
,而不是服务配置文件 ( web.config
)
采纳答案by markt
The default number of allowed concurrent connections is 10.
Most likely your client is not closing the connections.
允许的默认并发连接数为 10。
很可能您的客户端没有关闭连接。
To increase the number of concurrent calls, you will have to add your behavior to the service configuration, not the client.
要增加并发调用的数量,您必须将您的行为添加到服务配置中,而不是客户端。
回答by JP Alioto
Can you configure tracingand run the loop? It may be that the channel is becoming faulted and causing the client to time out.
您可以配置跟踪并运行循环吗?可能是通道出现故障并导致客户端超时。
回答by Thorarin
I ran into this problem this week and I wasn't able to quite figure out what was going on.
I actually did change my call to my service to Dispose()
the service client, but it didn't seem to have any effect. Apparently, there was another service call lurking somewhere.
本周我遇到了这个问题,但我无法弄清楚发生了什么。我实际上确实将我对服务的调用更改Dispose()
为服务客户端,但它似乎没有任何效果。显然,某处潜伏着另一个服务电话。
What may be interesting to note is what made me decide that this was notthe problem: this limit is not related to the actual number of socket connections to the webservice. When you hit the maxConcurrentSessions
limit, there is still only one actual socket connection. I was checking this with netstat
, which brought me to the wrong conclusion. So, don't confuse sessions with sockets.
可能有趣的是,是什么让我决定这不是问题:这个限制与 web 服务的实际套接字连接数无关。当您达到maxConcurrentSessions
限制时,仍然只有一个实际的套接字连接。我正在检查这个netstat
,这让我得出了错误的结论。所以,不要将 session 与 sockets 混淆。
We have interfaces defined for all our WCF services, so I'm planning to adapt this pattern in my code now:
我们为所有 WCF 服务定义了接口,所以我现在计划在我的代码中调整这种模式:
IMyService service = new MyServiceClient();
using (service as IDisposable)
{
service.MyServiceMethod();
}
What's also interesting, is that the problem did not occur for me when the services (and website) were hosted on IIS. The configuration is (almost) identical, yet I could not reproduce this behavior on that machine. I guess that's a good thing :)
同样有趣的是,当服务(和网站)托管在 IIS 上时,我并没有出现这个问题。配置(几乎)相同,但我无法在那台机器上重现这种行为。我想这是一件好事:)
@ John Saunders (about variable assignment in using
):
@ John Saunders(关于变量赋值using
):
I usually do put the variable assignment in the using
statement. But the IMyService that's generated is not implicitly convertible to IDisposable
. If you really wanted the assignment in there, I suppose the alternative would be:
我通常将变量赋值放在using
语句中。但是生成的 IMyService 不能隐式转换为IDisposable
. 如果你真的想要那里的任务,我想替代方案是:
IService service;
using ((service = new ServiceClient()) as IDisposable)
{
}
That still leaves the problem of the variable scope being wrong though. The reference to IService service
is unusable, but still in scope. So this would be better in that respect:
尽管如此,这仍然留下了变量范围错误的问题。对的引用IService service
不可用,但仍在范围内。所以这在这方面会更好:
using (IDisposable serviceDisposable = new ServiceClient())
{
IService service = (IService)serviceDisposable;
}
That requires me to introduce an extra variable name though. *Meh*
不过,这需要我引入一个额外的变量名称。*嗯*
回答by Suranga Bandara
This can be solved by creating singleton class as interface between web service reference and application. Then it will create only one instance of service reference.
这可以通过创建单例类作为 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();
}
}
回答by eduardo
A call to clientservice.close() will solve the problem.
调用 clientservice.close() 将解决问题。
回答by Avada Kedavra
After pulling my hairs over a muchsimilar problem that was not solved by either Close()
or Dispose()
I would like to add a simple solution that made my day, namely by increasing the ServicePointManager.DefaultConnectionLimit
which is by default 2.
在拉我的头发后,很多不是由解决类似的问题,无论是Close()
还是Dispose()
我想补充一个简单的解决方案,让我很快乐,即通过增加ServicePointManager.DefaultConnectionLimit
默认2这是。
"The DefaultConnectionLimit property sets the default maximum number of concurrent connections that the ServicePointManager object assigns to the ConnectionLimit property when creating ServicePoint objects."
“DefaultConnectionLimit 属性设置了 ServicePointManager 对象在创建 ServicePoint 对象时分配给 ConnectionLimit 属性的默认最大并发连接数。”
In my case my application successfully connected to my remote service 2 times, on the third attempt it simply did not try to connect to the service. Instead it waited for a while before timing out with the same error message as in the question above. Increasing DefaultConnectionLimit
resolved this. To add to the frustration this behavior was somewhat random - in one case of 10 the webservice was invoked successfully multiple (>2) times.
在我的例子中,我的应用程序成功连接到我的远程服务 2 次,在第三次尝试时它根本没有尝试连接到该服务。相反,它在超时之前等待了一段时间,并显示与上述问题相同的错误消息。增加DefaultConnectionLimit
解决了这个问题。更令人沮丧的是,这种行为有点随机 - 在 10 次的情况下,web 服务被成功调用多次 (>2)。
The solution originates and are further discussed these two threads: wcf-timeout-exception-detailed-investigationand wcf-service-throttling. solved my issue.
该解决方案源自并进一步讨论了这两个线程:wcf-timeout-exception-detailed-investigation和wcf-service-throttling。解决了我的问题。