我有一个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
)
答案 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上时,我没有遇到这个问题。配置(几乎)相同,但我无法在该计算机上重现此行为。我想这是一件好事:)
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-investigation和wcf-service-throttling。解决了我的问题。