我有一个WCF客户端/服务器应用程序,它使用WSHttpBinding通过HTTP进行通信 .
Server Setup :自托管,使用标准WCF ServiceHost
. 我的实际服务类别归结为:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
InstanceContextMode = InstanceContextMode.PerSession,
UseSynchronizationContext = false)]
Client Setup :使用visual-studio生成的客户端代理使用同步服务调用( proxy.call_server_method
阻止,直到服务器完全响应为止 . )
Scenario :我有一个特定的方法调用,需要20秒才能在服务器上执行 . 客户端在一个单独的线程中调用此方法,因此它不会被阻止, ConcurrencyMode.Multiple
表示WCF也应该在服务器上的单独线程中执行它 .
这个理论得到以下事实的支持:当我将我的应用配置为使用 NetTcpBinding
时,一切正常 .
Problem :
如果我将应用程序配置为使用 WSHttpBinding
,则此长方法调用会导致http请求'back up' . 我已经通过检查我的日志和使用fiddler调试HTTP请求来验证这种行为 .
例:
-
客户端在后台线程上发起20秒长请求
-
客户端在前台线程上启动请求B和C.
-
请求B和C被发送到服务器,在完成20秒长请求之前,服务器不处理它们
但有时候:
-
请求B和C不会被发送(它们甚至不会出现在小提琴中),直到20秒请求返回(这种情况很少见) .
-
注意:在客户端的app.config中设置
<add address="*" maxconnection="100"/>
会使此(似乎)停止发生 . -
请求B被立即发送并接收响应,而请求C被保留,直到20秒完成(这是罕见的)
这是来自提琴手演示问题的时间表:(点击查看大图)
如您所见,请求都在服务器上备份 . 一旦20秒的请求完成,响应都会泛滥,但请注意,有些请求没有被阻止......
所以, Questions :
-
这到底是怎么回事?为什么使用
NetTcpBinding
可以正常工作而不能使用WSHttpBinding
? -
为什么行为不一致?
-
我该怎么办才能修复它?
笔记:
-
它's not locking on the server. I'已设置断点并使用
!syncblk
并且它始终报告没有持有锁 . -
It 's not my threading (NetTcpBinding shouldn' t另有工作)
-
我在服务器的app.config中设置了
<serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000" />
-
这个20秒的呼叫只是在等待一个计时器,它不会颠覆CPU或磁盘或网络
-
我'd prefer a solution that didn' t涉及重新设计应用程序以使用异步调用...它想要弄乱我不理解的东西 .
8 回答
考虑在每个呼叫服务上使用ConcurrencyMode.Multiple以允许并发调用 .
我忘记了 - 它可以订购吗?我想也许RM over http可以保留顺序,但也许Tcp会话不会(除非你明确要求它)?服务 Contract 中是否有描述有序/无序会话的属性(我忘了) .
我认为您达到了协议限制并解决了它需要修改客户端计算机上的标准设置:
http://support.microsoft.com/kb/183110
http://support.microsoft.com/kb/282402
我猜WSHttpBinding在发出请求时使用WinINET设置 .
在WCF(.Net或Windows事物)之外有一些限制,默认只允许最多两个同时出站HTTP连接 . 不幸的是,我不记得我生命中的事物的名称(以及你在app.config或你的应用程序中覆盖它的内容) . 鉴于你没有看到请求离开客户端,并且它只是HTTP,我认为你正在打“那件事” . 我会继续寻找它的名字 .
更新:找到它 - 在客户端上尝试此操作(但将'2'更改为更大的数字):
我们在IIS / ASP.NET中托管了JSON服务,看到了完全相同的症状 .
根本原因最终是ASP.NET同步请求 - 而不是WCF . 我们必须禁用会话状态(在应用程序级别)以获取并发WCF方法 .
Web.config:
<system.web> <sessionState mode="Off" /> </system.web>
请注意,我们的服务使用webHttpBinding,而不是wsHttpBinding . 所以,我不确定这是否也解决了猎户座的问题 .
[自我回答向其他用户展示我们最终的解决方案]
最后,我从未设法解决这个问题 .
我们的最终解决方案是将我们的应用程序从
WSHttpBinding
切换到 生产环境 中的NetTcpBinding
- 我们一直计划最终出于性能原因这样做 .这是相当不幸的,因为它在
WSHttpBinding
上留下了一个黑色标记,可能有也可能没有保证 . 如果有人想出一个不涉及放弃的解决方案WSHttpBinding
,我很想知道它如果更改为BasicHttpBinding,它是否有效?
是这样,听起来喜欢this is your problem,会话限制,这让我陷入困境 .
不确定但有时来自silverlight应用程序的并发调用的问题与浏览器连接管理有关 . 对我来说,解决方案是将它放在我们的App.xaml.cs,Application_Startup方法中,如下所示:http://weblogs.asp.net/olakarlsson/simultaneously-calling-multiple-methods-on-a-wcf-service-from-silverlight