【发布时间】:2017-05-25 14:44:29
【问题描述】:
我们在应用程序中使用了大量自定义 Windows 服务。然而,我目前正在处理的问题有一个令人恼火的问题:当服务继续运行时,它只是停止运行。
服务的 Main 方法被包装在一个 try/catch 块中,如下所示:
static void Main()
{
IRepository rep = new Repository();
ILogger log = LogManager.GetLogger(GetType().Name);
TimeSpan loadWindowStart = new TimeSpan(9, 0, 0);
TimeSpan loadWindowEnd = new TimeSpan(18, 0, 0);
foreach (SuppressionLoad sl in rep.GetSuppressionLoads().ToList())
{
try
{
// do stuff
}
catch(Exception ex)
{
// log error
}
}
}
该服务还会在它做的事情时记录下来,我们可以在它忙碌的时候看到日志填满。
但是,有时日志会停止。数据库中其他地方的活动表明整个服务已经停止工作。签入服务器上的服务,该服务仍显示“已启动”状态。在这种状态下,它占用的系统资源几乎为零,尽管它通常是处理器密集型的。如果您尝试阻止它,它只会尝试超时,而且据我们所知,它永远不会自行停止。该进程必须在任务管理器中终止。
在前往这些摊位的过程中,日志中没有任何不妥之处。我们在事件查看器中也找不到任何东西。
由于它没有记录错误,我不知道这里发生了什么,或者我们可以做些什么来尝试从这里诊断故障。它是高度间歇性的——它通常会在进入状态之前运行几天而没有问题。我们可以做些什么来调查发生了什么?
【问题讨论】:
-
听起来您需要查看服务的代码,开始使用调试器并逐步执行代码..也许您可能需要考虑更改日志记录的方式..也许写直接写入日志文件或每次都创建一个新的日志文件。
-
@MethodMan 单步执行没问题,但是这种故障断断续续,并不是真正的实用选择。
-
听起来问题可能在任何地方,不一定与提供的代码有太大关系。一个建议:当服务挂起时,附加一个调试器并查看线程以及每个线程的位置。要问的问题:是我所期待的所有线程还是有些已经消失或下落不明。线程是否陷入死锁(我怀疑这是正在发生的事情),如果是这样,在什么资源上。打开详细的日志记录并添加更多的调试日志语句,以隔离它上次在代码流中的位置和没有到达的位置,然后继续缩小位置。
-
这听起来像死锁。您应该能够使用任务管理器进行小型转储,并在 WinDbg 等调试器中对其进行分析。 WinDbg 具有查找同步对象锁定的命令(我相信
!locks可以做到这一点)。 -
会不会是日志系统出错了?那个可能不会在你的 try/catch 块中被捕获。假设有故障导致服务器中断并且无法记录。尝试每 x 秒记录一次滴答,当服务失败时,查看最后一次滴答时的 Windows 事件日志,看看系统可能注意到了其他事情。
标签: c# windows windows-services