我们有一个C#(。Net 4.0)控制台应用程序“自托管”两个WCF服务:一个使用WSHttpBinding
,另一个使用BasicHttpBinding
。
连接到这些服务,我们有两个独立的客户端应用程序:使用BasicHttpBinding
的基于Silverlight的服务,以及使用WSHttpBinding
的另一个控制台应用程序。
WCF服务应用程序通常有大约30个用户通过Silverlight客户端连接,另外几个连接来自控制台应用程序客户端。它无论如何都不是“平坦的”;每个客户端最多可以每5秒查询一次WCF服务。
问题是:间歇性地使服务应用程序无响应。虽然服务器本身继续运行(它继续写入日志文件),但所有WCF活动(在ServiceHost
上)都显示为“占用”。不处理新请求(尽管接受TCP连接)。此外,应用程序消耗的线程数开始急剧增加,速度大约为每秒一个新线程。代码本身不会对Thread
或ThreadPool
执行任何操作,但偶尔会发出Thread.Sleep
几百毫秒。
令人沮丧的是问题的间歇性:代码定期运行数小时,甚至几天没有任何问题。然后,没有明显的原因,它突然变得没有响应,线程计数开始滴答。
我尝试过模拟用户活动 - 连接和断开客户端,“淹没”服务请求 - 但我无法重现错误。
如果问题是WCF Throttling,我已添加此代码:
ServiceThrottlingBehavior throttlingBehavior = new System.ServiceModel.Description.ServiceThrottlingBehavior
{
MaxConcurrentCalls = 512,
MaxConcurrentInstances = 8192,
MaxConcurrentSessions = 8192
};
host.Description.Behaviors.Add(throttlingBehavior);
host2.Description.Behaviors.Add(throttlingBehavior);
..没有明显效果。
我在代码中进行了大量的日志记录,以尝试确定触发此行为的内容 - 记录每个调用每个方法 - 但结果没有出现任何内容。我已将try
... catch
块中的所有内容都包装起来,并将任何异常吐出到日志文件中,以查看某些内容是否落在某处,并将UnhandledException
陷入类似的情况时尚......但是,似乎没有什么事情会出错。
上述行为对任何人来说都是熟悉的,或者有人可以就解决此问题的最佳方法提出建议吗?
编辑:按照下面Wal的建议,我在应用程序开始出现错误时捕获了.DMP,并查看VS2012中的Parallel Stacks视图,我看到了:
......和其他非常相似但线程数不同的人。我不够聪明地解释这意味着什么..谁能建议从哪里开始寻找下一个?
答案 0 :(得分:2)
该服务的并发模式是什么?和instancecontextmode? p>
默认的instancecontextmode是每个会话,可能值得将此更改为percall,这将使用更多内存,但将确保每个服务实例都没有闲置(假设客户端已正确处理http://coding.abel.nu/2012/02/using-and-disposing-of-wcf-clients/)< / p>
答案 1 :(得分:2)
正如早些时候所指出的那样,听起来你有竞争条件。您是否有机会检查代码中某处连接的System.ServiceModel.ICommunicationObject.State?见MSDN article:
Checking the value of the System.ServiceModel.ICommunicationObject.State property is
a race condition and is not recommended to determine whether to reuse or close a channel.
答案 2 :(得分:2)
感谢所有评论和回答的人;你的建议和意见确实有所帮助 - 尤其是确认它似乎并不是我错过的那些微不足道的东西。
然而,有点令人沮丧的是,这个问题似乎已经消失了。这就是我改变的内容:
应用程序定期写入控制台(我的“WriteToLog”方法有Console.WriteLine
以及附加到文件;这在开发期间纯粹是为了我自己的方便)。该应用程序也使用FireDaemon作为服务运行,由于某种原因,我们开始在conhost.exe
上看到高CPU时间。所以为了抵消这一点,我已经评论了Console.WriteLine
。
由于CPU率很高,我们还增加了运行代码的虚拟机的性能,增加了几个核心。
因此,就CPU使用率而言,应用程序现在更加“安静”。正如其他人所提到的那样,代码中的某些地方几乎肯定存在“竞争条件”,但通过使底层机器更快并且代码更高效,几乎可以看出我已经减少了竞争条件发生的可能性。当然,至少每天发生一次的问题在近一周内没有发生过。
为了确保,我已经完成了代码并确保每个共享对象都包含在Lock()
中,其中有任何可能被另一个线程修改 - 即使我没有做任何显式线程,我假设WCF机制会自动执行此操作,并且有可能传入请求尝试修改对象,而其他东西正在咀嚼它。如果发生这种情况,我本来期望某种并发异常?
再次感谢您的帮助,我希望在点击Post Your Answer
按钮后代码不会失效:/
答案 3 :(得分:0)
可能是它与WCF无关的线程问题 - 正如之前的帖子中所提到的,锁定语句可能是嫌疑人 - 你的应用程序(WCF部分与否),可能已经启动线程,由于无法退出锁定问题。
另一方面,它可能是WCF,你的WCF服务受到了很多打击吗?试试节流。 http://msdn.microsoft.com/en-us/library/system.servicemodel.description.servicethrottlingbehavior.maxconcurrentinstances.aspx