C#Timer on Elapsed Time不调用方法

Hat*_*oft 2 .net c# multithreading timer .net-4.0

以下类来自.Net Windows服务.DoSomeDatabaseStuff方法在第一次启动时需要10分钟,但是当时间结束时,此方法不会再次被调用.

public class Test
{
        public void Start()
        {
            DoSomeDatabaseStuff();

            _oTimer = new Timer(60000);
            _oTimer.Elapsed += OnTimeout;
            _oTimer.AutoReset = true;
            _oTimer.Start();
        }

        private void OnTimeout(object source, ElapsedEventArgs e)
        {
            DoSomeDatabaseStuff();

            _oTimer = new Timer(60000);
            _oTimer.Elapsed += OnTimeout;
            _oTimer.AutoReset = true;
            _oTimer.Start();
        }
}
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 6

此代码中存在许多严重问题:

  • 如果Start方法是服务的OnStart()方法,那么您永远无法启动服务.OnStart()必须在30秒内完成.只需初始化计时器,不要做任何其他事情
  • 在Elapsed事件处理程序中创建另一个Timer是一个严重的错误.您的事件处理程序现在将运行两次.在第二次调用之后,它将运行三次.等等.
  • 您的测试程序不会测试代码在服务中运行的方式.Elapsed事件处理程序将永远不会运行,因为测试将在您的事件处理程序运行之前完成.这解释了你的观察
  • 必须在Elapsed事件处理程序中使用try/catch.如果不这样做,那么在没有诊断的情况下将吞下任何异常.该System.Timers.Timer类是讨厌这样,有利于System.Threading.Timer而是还介绍你的观察
  • 必须确保您的事件处理程序是可重入的.它可以再次运行时,事件处理程序的前面调用还在忙碌,当任务需要超过一分钟会出现这种情况.这很少有好结果.设置自动复位=假是一种简单的方法来避免这种重入,开始计时备份在事件处理结束让它重复.