12

我们有一个 C# (.Net 4.0) 控制台应用程序,它“自托管”两个 WCF 服务:一个 used WSHttpBinding,另一个使用BasicHttpBinding.

连接到这些服务后,我们有两个独立的客户端应用程序:一个BasicHttpBinding使用WSHttpBinding.

WCF 服务应用程序通常有大约 30 个用户通过 Silverlight 客户端连接,另外几个来自控制台应用程序客户端的连接。无论如何,它都不是“平淡无奇”。每个客户端最多每 5 秒查询一次 WCF 服务。

问题是:服务应用程序间歇性地变得无响应。尽管服务器本身继续运行(它继续写入日志文件),但所有 WCF 活动(在两个ServiceHosts 上)似乎都“占用”了。不处理新请求(尽管接受 TCP 连接)。此外,应用程序消耗的线程数开始急剧增加,大约每秒一个新线程。代码本身不会对Threads 或ThreadPools 做任何事情,尽管它偶尔会发出Thread.Sleep几百毫秒的 a。

令人沮丧的是问题的间歇性:代码定期运行数小时,甚至数天而没有任何问题。然后,在没有明显原因的情况下,它突然变得无响应并且线程数开始增加。

我尝试过模拟用户活动——连接和断开客户端,用请求“淹没”服务——但我无法重现故障。

以防万一问题是 WCF 限制,我添加了以下代码:

 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以类似的方式将 s 困住了……但再一次,似乎没有任何问题。

上述行为是否对任何人来说都很熟悉,或者任何人都可以建议解决此问题的最佳方法吗?

编辑:按照下面 Wal 的建议,当应用程序开始出现异常行为时,我已经捕获了应用程序的 .DMP,并查看了 VS2012 中的 Parallel Stacks 视图,我看到:

在此处输入图像描述 在此处输入图像描述

...和其他非常相似但线程数不同的。我不够聪明,无法准确解读这意味着什么……有人可以建议下一步从哪里开始寻找吗?

4

4 回答 4

2

服务的并发模式是什么?和实例上下文模式?

默认 instancecontextmode 是每个会话,可能值得将其更改为 percall,这将使用更多内存但将确保每个服务实例都不会闲逛(前提是客户端正确处理http://coding.abel.nu/ 2012/02/使用和处置-wcf-clients/ )

于 2013-06-06T15:51:15.677 回答
2

正如之前指出的那样,听起来您有竞争条件。您是否没有机会检查代码中某处连接的 System.ServiceModel.ICommunicationObject.State ?请参阅MSDN 文章

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.
于 2013-06-07T12:38:10.943 回答
2

感谢所有评论和回答的人;你的建议和意见真的很有帮助——尤其是确认这似乎不是我错过的微不足道的事情。

然而,有点令人沮丧的是,这个问题似乎已经消失了。这是我所做的更改:

  • 该应用程序定期写入控制台(我的“WriteToLog”方法有Console.WriteLine以及附加到一个文件;这纯粹是为了我自己在开发过程中的方便)。该应用程序还使用 FireDaemon 作为服务运行,出于某种原因,我们开始看到高 CPU 时间在conhost.exe. 所以为了抵消这一点,我注释掉了Console.WriteLine.

  • 由于 CPU 较高,我们还通过向其添加更多内核来提高运行代码的虚拟机的性能。

因此,应用程序现在在 CPU 使用率方面更加“安静”。正如其他人所提到的,几乎可以肯定代码中的某个地方存在“竞争条件”,但是通过使底层机器更快并且代码更高效,似乎我已经减少了竞争条件发生的机会。当然,每天至少发生一次的问题在近一周内都没有发生过。

可以肯定的是,我已经检查了代码并确保每个共享对象都被包装在一个Lock()有可能被另一个线程修改的地方——即使我没有做任何显式线程,我假设WCF 机制将自动执行此操作,并且传入请求可能会尝试和修改对象,而其他东西正在咀嚼它。如果发生这种情况,我会期待某种并发异常吗?

再次感谢您的帮助,希望在我单击按钮后代码不会崩溃Post Your Answer:/

于 2013-06-11T08:09:29.773 回答
0

可能是它与 WCF 无关的线程问题 - 正如在之前的帖子中提到的,锁定语句可能是可疑的 - 您的应用程序(WCF 部分与否)可能已经启动了线程,由于锁定问题而无法退出。

另一方面,它可能是 WCF,您的 WCF 服务是否受到很多打击?试试油门。 http://msdn.microsoft.com/en-us/library/system.servicemodel.description.servicethrottlingbehavior.maxconcurrentinstances.aspx

于 2013-12-08T04:36:24.893 回答