代码之家  ›  专栏  ›  技术社区  ›  Biri

带有计时器的.NET Windows服务停止响应

  •  18
  • Biri  · 技术社区  · 16 年前

    public partial class ArchiveService : ServiceBase
    {
        Timer tickTack;
        int interval = 10;
        ...
     
        protected override void OnStart(string[] args)
        {
            tickTack = new Timer(1000 * interval);
    
            tickTack.Elapsed += new ElapsedEventHandler(tickTack_Elapsed);
            tickTack.Start();
        }
    
        protected override void OnStop()
        {            
            tickTack.Stop();
        }    
        
        private void tickTack_Elapsed(object sender, ElapsedEventArgs e)
        {
            ...
        }
    }
    

    它工作一段时间(比如10-15天),然后停止。我的意思是服务显示为正在运行,但它什么也不做。我做了一些日志记录,问题可能是计时器,因为在间隔之后,它不会调用tickTack_appeased函数。

    计时器是从System.Timers命名空间使用的,环境是Windows 2003。我在不同服务器上的两个不同服务中使用了这种方法,但两者都产生了这种行为(这就是为什么我认为它以某种方式连接到我的代码或框架本身)。


    我编辑了这两个服务。其中一个在任何地方都得到了很好的尝试和更多的记录。第二个人定期参加计时器娱乐活动。从那以后,他们都没有停止过,所以如果这种情况再持续一周,我将结束这个问题。谢谢大家到目前为止。


    编辑:

    我结束这个问题是因为什么都没发生。我的意思是,我做了一些更改,但这些更改在这件事上并不真正相关,从那时起,这两项服务都在运行,没有任何问题。请将其标记为“因不再相关而关闭”。

    7 回复  |  直到 4 年前
        1
  •  18
  •   Steven A. Lowe    16 年前

    将计时器代码的主体包装在try-catch块中

        2
  •  5
  •   StingyJack    16 年前

    我以前在计时器和循环服务中都见过这种情况。通常情况下,捕获的异常会停止计时器或循环线程,但不会作为异常恢复的一部分重新启动它。

    我不认为计时器有什么“优雅”的地方。对我来说,在代码中看到循环操作比计时器方法更直接。但优雅是主观的。

        3
  •  4
  •   jro    16 年前

    http://support.microsoft.com/kb/842793

    这是一个已知的bug,它在框架中多次出现。

    您的里程数可能会有所不同,因此请使用操作系统/框架位的组合进行验证。

        4
  •  3
  •   Nickolodeon    13 年前

    正如许多受访者指出的那样,例外情况被计时器吞没了。在windows服务中,我使用System.Threading.Timer。它具有Change(…)方法,允许您启动/停止计时器。可能出现异常的地方可能是可重入性问题——以防tickTack_执行时间超过计时器周期。通常我会这样编写计时器循环:

        void TimeLoop(object arg)
        {
            stopTimer();
    
            //Do some stuff
    
            startTimer();
        }
    

    你也可以 lock(...) 您的主循环可以防止重入。

        5
  •  3
  •   Marc Gravell    16 年前

    private void tickTack_Elapsed(object sender, ElapsedEventArgs e)
    {
        CheckForRecycle();
        // ... actual code
    }
    
    private void CheckForRecycle()
    {
        lock(someLock) {
            if(++tickCount > MAX_TICKS) {
                tickCount = 0;
                tickTack.Stop();
                // re-create timer
                tickTack = new Timer(...);
                tickTack.Elapsed += ...
                tickTack.Start();
            }
        }
    }
    

    您可能会将其中的部分与 OnStart / OnStop

        6
  •  0
  •   PEZ    16 年前

        7
  •  0
  •   Stefan    16 年前

    在一些项目中,我和你做的完全一样,但没有问题。

    您的tickTac_中是否有可能导致此问题的代码?比如一个永不结束的循环,或者某个停止计时器的错误,使用线程并等待这些线程的结束,等等?