3

我试图让计时器每分钟运行一次,与系统时钟(00:01:00、00:02:00、00:03:00 等)同步。下面的代码会产生一个稳定的计时器吗?我试过运行它。计时器确实每分钟精确运行一次。但问题是它会在几个月后开始徘徊吗?

private System.Timers.Timer timer;

public frmMain()
{
            timer = new System.Timers.Timer();
            timer.AutoReset = false;
            timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
            timer.Interval = GetInterval();
            timer.Start();
}

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
            //Do processing

            timer.Interval = GetInterval();
            timer.Start();

}
private double GetInterval()
{
            DateTime now = DateTime.Now;
            return ((60 - now.Second) * 1000 - now.Millisecond);
}
4

4 回答 4

4

它不会。

DateTime.Now使用系统时钟作为参考计时器,因此您的计时器将始终与它保持同步,以系统时钟分辨率的几毫秒为模。

于 2012-06-13T11:46:48.703 回答
0

大图看起来不错,GetInterval总是会返回一个正值,等等。我只看到一些警告:

  1. 如果发生待机/恢复,那么您可能会在非回合时间运行一次
  2. 如果 timer_Elapsed 需要超过一分钟才能完成,那么您将错过一个节拍
  3. 如果系统过载以至于 timer_Elapsed 计划延迟 40/50 秒并且 timer_Elapsed 花费超过60 - delay几秒,您将错过一个节拍
于 2012-06-13T11:58:59.883 回答
0

您的代码不会漂​​移,但会(不可避免地)出现抖动,因为 Timer 回调很少会在请求的时间间隔内发生。

我可以看到此代码的唯一潜在ThreadPool问题是,如果您的计时器回调没有出队并在一分钟间隔内执行,从而导致跳过一分钟。

这似乎不太可能,但并非完全超出可能性范围。

于 2012-06-13T11:54:18.027 回答
0

我看不出它是如何消失的,每次计时器滴答作响时,它都会确定到下一分钟的确切时间并相应地设置间隔。理论上它实际上是相当巧妙的,因为我自己的计时器会跑掉。当然,唯一可以确定的方法是对其进行测试,因此只要您的 UI 不冻结超过 60 秒(为了安全起见,可能需要 50 秒),就不会有问题。请记住,笔记本电脑通常会在放置一段时间后进入睡眠状态,或者盖上盖子,这会导致故障。

但是,根据您尝试执行的操作,为什么不使用系统时间在每次分钟更改时发送事件?

于 2012-06-13T11:47:36.667 回答