Windows服务中的计时器未触发ElapsedEventHandler

时间:2011-08-17 14:37:47

标签: c# timer

我有一个用C#编写的Windows服务,可以正确执行方法。我添加了一个计时器来安排方法执行,它似乎没有触发ElapsedEventHandler事件。

System.Timers.Timer timer = new System.Timers.Timer();

public LabelService()
        {
            InitializeComponent();
            timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
        }


public void SetTimer()
        {
            DateTime nextRunTime = GetNextRunTime();
            var ts = nextRunTime - DateTime.Now;
            timer.Interval = ts.TotalMilliseconds;
            timer.AutoReset = false;
            timer.Start();
        }

void timer_Elapsed(object source, ElapsedEventArgs e)
        {
           // ** never gets here **
            timer.Stop();
              // run some code
            SetTimer();
        }

我可以在timer.Start();运行并点击一个断点,所以我知道它已经完成,但它永远不会落入timer_Elapsed方法。 (对于测试,我将ts.TotalMilliseconds更改为1000)任何想法?

3 个答案:

答案 0 :(得分:1)

“如果Enabled设置为true且AutoReset设置为false,则Timer会在第一次间隔过去时仅将Elapsed事件提升一次。当Enabled为true且AutoReset为true时,Timer会继续提升Elapsed事件在指定的时间间隔。“

所以我认为你必须设置

timer.AutoReset = true;

答案 1 :(得分:1)

我知道这已经过时了,但对于遇到同样问题的其他人我可以通过使用来解决这个问题;

public void StartTimer()
{
    _timer.Interval = _pollingIntervalMilliseconds;
    _timer.Enabled = true;
    _timer.AutoReset = false; // We must manually restart the timer when we have finished processing
    _timer.Elapsed += CheckForUpdates;
    _timer.Start();
    if (Environment.UserInteractive)
    {
        Console.WriteLine("System now running, press a key to Stop");
        Console.ReadKey();
    }
}
private void CheckForUpdates(object sender, ElapsedEventArgs e)
{
    Console.WriteLine("Checking For Update");
    DoSomethingSlow();
    _timer.Start(); // restarts the timer to hit this method again after the next interval
}

它会一直击中经过的事件,直到你按一个键退出

答案 2 :(得分:0)

关于这个问题的评论,你说你这样称呼它:

#if (!DEBUG) 
    ServiceBase[] ServicesToRun; 
    ServicesToRun = new ServiceBase[] { new LabelLoader() }; 
    ServiceBase.Run(ServicesToRun); 
#else 
    LabelLoader ll = new LabelLoader(); 
    ll.Start(); 
#endif

如果您处于调试模式,这意味着您的主要方法是:

    LabelLoader ll = new LabelLoader(); 
    ll.Start(); 

这意味着一旦它运行了这两行,程序就会运行并且可能会退出。无论你的计时器到底是什么,程序都已退出,因此你的计时器永远不会启动。

我建议用更好的线束测试你的ll。就个人而言,我使用winform类型的界面,只需要一个开始按钮来模仿服务启动(然后将按钮单击中的代码)。一旦我认为我的代码按照我的意愿运行,那么我就在服务环境中进行测试。