当控制台应用程序使用完全相同的基本库执行完全相同的操作时,可能导致Windows服务挂起的原因是什么?

时间:2009-12-03 17:40:57

标签: c# windows-services

我讨厌提出这样的问题 - 它们是如此不确定......并且无法确定,但这里也是如此。

背景: 我有一个DLL,它是一个定时进程的应用程序的内核。我的计时器接收运行它的间隔的配置和一个应该在间隔过去时运行的委托。我有另一个DLL包含我注入的进程。

我创建了两个应用程序,一个Windows服务和一个控制台应用程序。每个应用程序都读取自己的配置文件并加载相同的库,推送配置的计时器间隔并委托给我的定时进程类。

问题: 昨天和最后 n 周,使用Windows服务在我们的生产环境中一切正常。今天,Windows服务将运行大约20-30分钟并挂起(计时器间隔为30秒),但控制台应用程序运行没有问题,并且在过去4小时内运行。详细记录不表示任何故障。就像Windows服务只是......悄然死去 - 不停地停止。

鉴于我的Windows服务和控制台应用程序正在做同样的事情,我只能认为有些东西导致Windows服务进程挂起 - 但我不知道是什么原因造成的。我检查了配置文件,它们都是相同的 - 我甚至将其中的内容复制并粘贴到另一个中以确保。没有骰子。

当使用相同基本库的对应控制台应用程序没有时,任何人都可以就可能导致Windows服务挂起的内容提出建议;或者任何人都可以指向我的工具方向,这将允许我诊断可能导致此问题的原因?

感谢大家的帮助 - 仍然在挖掘。

8 个答案:

答案 0 :(得分:8)

您需要弄清楚生产服务器上发生了哪些变化。起初,负责的IT人员会发誓,没有任何改变,但你必须坚持不懈。我已经看到这种情况经常发生在我身上。 软件不会破坏。期间。 必须改变环境。

执行方面的差异:您有两个运行相同代码的应用。最可能的区别(和罪魁祸首)是该服务使用与您的控制台应用程序不同的安全凭证集运行,并且可能成为安全变幻莫测的牺牲品。先检查一下。哪个Windows帐户正在运行该服务?它的作用和范围是什么?是否有任何第三方安全软件在服务器上运行,并且可能会杀死错误的应用程序?您是否必须使用第三方安全服务注册您的服务?您的.Net程序集是否正确签名?您的.Net程序集是否在服务器上正确注册和配置?最后但并非最不重要的一点是,不要忘记,调试器用户(很可能是这样)可以获得比其他许多帐户类型更多的东西。

另一个想法:由于时间似乎是问题的一部分,请检查计算机上的计划任务。也许有一个过程会每30分钟就会发生一次干扰你自己的过程。

答案 1 :(得分:3)

您可以按running it interactively within Visual Studio调试Windows服务。这可以帮助您通过设置(可能是条件的)断点来隔离问题。

或者,您可以使用Visual Studio“附加到进程”对话框窗口查找服务进程,并在启用“Debug CLR”选项的情况下将其附加到该对话框。同样,这允许您根据需要设置断点。

你在使用任何断言吗?如果断言在没有被重定向写入日志文件的情况下触发,则您的服务将挂起。如果代码抛出未处理的异常,可能是因为内存泄漏,那么您的服务进程将崩溃。如果将服务控制管理器(SCM)设置为在发生崩溃时重新启动进程,则应该能够看到服务已重新启动。由于您在两种环境中都运行相同的代码,因此这两种情况似乎不太可能。但请记住,您的服务由SCM托管,这意味着与运行控制台应用程序的环境截然不同。

我经常使用“心跳”,其中服务中的每个活动线程向本地MSMQ发送常规(例如每30秒)消息。这可以实现手动或自动监控,并在这些心跳消息到达时为您提供一些线索。

另一种可能性是某种权限问题,因为该服务可能与控制台的其他本地/域用户一起运行。

挂起后,您可以使用SCM停止服务吗?如果你不能,那么可能存在某种线程死锁问题。服务似乎挂起后,您可以转到命令行并键入 sc queryex servicename 。这应该为您提供服务的当前状态。

答案 2 :(得分:1)

我可能会进行一些文件记录只是为了查看程序的进度。它可以让您更好地了解循环/挂起/死锁/崩溃的内容。

答案 3 :(得分:1)

您可以尝试这些技巧

  • 记录开始记录服务中代码的流程。有这个参数,所以你完成后没有洪水。您应该记录所有函数名称,参数,时间戳。

  • 附加调试器本地或远程将带有代码的调试器附加到正在运行的服务,设置适当的断点(可以基于从日志记录中收集的数据)

  • PerfMon 运行此实用程序并收集有关运行该服务的计算机的信息,以获取任何其他线索(高CPU峰值,IO峰值,过度分页等)

答案 4 :(得分:0)

Microsoft在debugging a Windows Service上提供了一个很好的资源。这基本上听起来像你必须要做的,因为你的问题是如此通用。话虽如此,过去几天对系统有任何改变可能会对服务产生负面影响吗?您是否对代码进行了任何更新,以改变服务可能的工作方式?

同样,我认为你将不得不做一些严肃的调试来找到你的问题。

答案 5 :(得分:0)

您在Windows服务中使用什么类型的计时器?我见过SO上有很多人有定时器和Windows服务的问题。 Here是一个很好的教程,只是为了确保您正确设置并使用正确类型的计时器。希望有所帮助。

答案 6 :(得分:0)

参考psasik的答案的另一个潜在问题是,如果您的应用程序依赖于仅在用户模式下运行时可用的内容。

在服务模式下运行(是桌面数据?),如果你试图确定只能在用户模式下看到的状态,可能会导致我的体验出现一些问题。

答案 7 :(得分:0)

闻起来像是一个线程问题。是否有任何线程或异步工作?一个关键问题是“服务每次都挂在同一行代码或相同的方法上吗?”使用您的日志记录查找挂起之前发生的最后事情,如果是,请发布问题代码。

您可能考虑的另一个工具是一个好的剖析器。如果它是.NET代码,我相信RedGate ANTS可以监控它并为您提供任何线程锁场景的良好画面。