WCF"自托管"应用程序变得无法响应

Ken*_*enD 12 .net c# wcf

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

连接到这些服务,我们有两个独立的客户端应用程序:使用该服务器的基于Silverlight的服务BasicHttpBinding,以及使用该服务器的另一个控制台应用程序WSHttpBinding.

WCF服务应用程序通常有大约30个用户通过Silverlight客户端连接,另外几个用户从控制台应用程序客户端连接.它无论如何都不是"平坦的"; 每个客户端最多可以每5秒查询一次WCF服务.

问题是:间歇性地使服务应用程序无响应.虽然服务器本身继续运行(它继续写入日志文件),但所有WCF活动(两者都ServiceHost显示)似乎"抓住".不处理新请求(尽管接受TCP连接).此外,应用程序消耗的线程数开始急剧增加,速度大约为每秒一个新线程.代码本身对Threads或ThreadPools 没有任何作用,尽管偶尔会发出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);
Run Code Online (Sandbox Code Playgroud)

..没有明显的效果.

我已经在代码中进行了大量的日志记录,以尝试确定触发此行为的内容 - 将每个调用记录到每个方法 - 但结果没有出现任何内容.我已将所有内容包装在try... catch块中,并将任何异常分散到日志文件中,以查看某些内容是否落在某处,并且还UnhandledException以类似的方式捕获了s ......但同样,似乎没有任何错误.

上述行为对任何人来说都是熟悉的,或者有人可以建议最好的方法来解决这个问题吗?

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

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

......和其他非常相似但线程数不同的人.我不够巧妙地解释这意味着什么..谁能建议从哪里开始寻找下一个?

Ken*_*enD 2

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

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

  • 该应用程序定期写入控制台(我的“WriteToLog”方法具有Console.WriteLine附加到文件的功能;这纯粹是为了我自己在开发过程中的方便)。该应用程序还使用 FireDaemon 作为服务运行,由于某种原因,我们开始在conhost.exe. 因此,为了解决这个问题,我注释掉了Console.WriteLine.

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

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

可以肯定的是,我已经检查了代码并确保每个共享对象都包装在一个Lock()可能被另一个线程修改的地方 - 即使我没有执行任何显式线程处理,我假设WCF 机制会自动执行此操作,并且当其他对象正在占用某个对象时,传入请求可能会尝试修改该对象。如果发生这种情况,我会预期会出现某种并发异常?

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