Windows服务应用程序挂起

背景:
– 运行Window Server 2008 R2。
服务器已经被修补了所有最新的更新。
– 服务器运行.NET 3.5中build立的5个服务,所有这些服务使用定时器来重复检查数据库(大部分每10秒钟)。
– 这些服务不是CPU / RAM密集型的。
– 服务器没有任何性能和资源问题或瓶颈。

在大多数情况下,一切都按预期工作,但是有时候一些(或全部)服务停止工作。 我将所有的应用程序exceptionlogging到文件中,但在失败时没有。 事件logging器中也没有错误,服务pipe理器将服务视为正在运行。 我必须停止服务并再次启动它们以恢复function。

这种行为是不可预知的,有时需要一个星期或一个月才能停止工作。 另外,有时这些服务在同一时间“死亡”在一起,或者只有一些“死亡”。

只有我想到的是Timer对象。 我一直在使用System.Timers.Timer,并发现多个论坛线程指出它是不可靠的垃圾收集器可能释放实例。 我试着用GC.KeepAlive()来保留它没有用。 我已经遵循了一些关于将System.Timers.Timer移动到System.Threading.Timer的build议,但是这也没有任何区别。

就在此刻,我不顾一切地找出这种行为的来源。 有没有已知的类似问题? 当没有exception提出并且事件日志也保持沉默时,我怎么能debugging它?

感谢您的任何build议,可能会导致任何解决scheme。

更新:包括当前状态的裸机代码:

private System.Threading.Timer timerPublish = null; private bool timerDelegateMethodRunning = false; protected override void OnStart(string[] args) { SetupTimer(); } protected override void OnStop() { if (timerPublish != null) { timerPublish.Dispose(); } } public void SetupTimer() { if (timerPublish != null) { timerPublish.Dispose(); } TimerCallback callbackMethod = new TimerCallback(this.timerPublish_Elapsed); timerPublish = new System.Threading.Timer(callbackMethod, null, 5000, 5000); } void timerPublish_Elapsed(Object stateInfo) { if (timerDelegateMethodRunning) { return; } timerDelegateMethodRunning = true; try { // Processing code here } finally { timerDelegateMethodRunning = false; } } 

UPDATE2:谢谢你们的见解和build议。 一旦问题再次出现,我将尝试debugging生产服务器上的服务。 一旦我有新的东西(可能在几个星期之内),我会立即报告。

你为什么使事情复杂化? :)只要使用Timer.Change()方法在准备就绪后再次触发定时器。

也知道在WorkerMethod中任何未被捕获的异常都会使你的服务崩溃。

 public class YourService { private System.Threading.Timer _timer; protected override void OnStart(string[] args) { //run once in 5 seconds. _timer = new System.Threading.Timer(WorkerMethod, null, 5000, Timeout.Infinite); } protected override void OnStop() { if (_timer != null) { _timer.Dispose(); _timer = null; } } void WorkerMethod(object state) { // Processing code here _worker.Change(5000, Timeout.Infinite); //Run again in 5 seconds } } 

更新

我看到你在哪里使用System.Timers.Timer 。 最大的问题是它忽略了例外 。 也就是说,如果你的代码抛出了一个异常,但你不知道: 你永远不会意识到这个异常 。 这可能是你的问题。

不要过早地得出结论,然后才能知道挂起的原因是什么。 可能有各种令人难以置信的因素,但转储分析或现场调试可以告诉你的真相,

http://blogs.msdn.com/b/tess/archive/2006/10/16/net-hang-debugging-walkthrough.aspx

如果你愿意,你甚至可以通过http://support.microsoft.com打开一个支持案例

无论如何,我可能会建议为您的服务稍微改变一下模式。 在那里我们有一个readonly Timer ,它在初始赋值之后,简单地被切换到运行,而不是在一分钟内发生的方式,同时也保留我们自己对TimerCallback的硬引用。 实际上,我们把物品放置到服务本身(至少是我们所困扰的长期物体)。

虽然这种模式可能不是你帽子里的白兔子,但我可以保证以这种方式构建的许多服务的可靠性。 因此,如果在执行这些问题后出现问题,那么我会高度自信地说, // Processing code here本身是有问题的。

 private readonly System.Threading.Timer Timer = null; private readonly System.Threading.TimerCallback Callback = null; private readonly int Interval = 5000; public MyService() { Callback = new TimerCallback(this.timerPublish_Elapsed); Timer = new System.Threading.Timer(Callback, null, Timeout.Infinite, Timeout.Infinite); } private void Start() { Timer.Change(Timespan.Zero, Interval); } private void Stop() { Timer.Change(Timeout.Inifinite, Timeout.Inifnite); } protected override void OnStart(string[] args) { Start(); } protected override void OnStop() { Stop(); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if(disposing) { if(Timer != null) Timer.Dispose(); } }