.NET计时器,它们是以确切的间隔还是在处理+间隔之后触发

时间:2011-08-28 00:38:54

标签: c# multithreading timer thread-sleep

这是一个非常简单的问题。

System.Timers的间隔究竟是如何工作的?

无论超时事件需要多长时间,或者它是否需要例程先完成然后重新启动间隔,它是否每秒触发1秒;

所以:

  1. 1秒...... 1秒...... 1秒等等
  2. 1秒+处理时间...... 1秒+处理时间...... 1秒+处理时间等等
  3. 我问这个的原因是我知道我的“处理”花了不到1秒的时间,但我想在点上每隔一秒发射一次(或尽可能接近)。

    我一直在使用Thread.Sleep方法,如下所示:

    Thread.Sleep(1000 - ((int)(DateTime.Now.Subtract(start).TotalMilliseconds) >= 1000 ? 0 : (int)(DateTime.Now.Subtract(start).TotalMilliseconds)));
    

    在例程开始时注册开始时间。 这里的问题是Thread.Sleep仅在毫秒内工作。所以我的例行程序可能会在1000毫秒或1000.0234毫秒之间重新启动,这可能发生,因为我的一个例程根据“TimeSpan”需要0毫秒,但显然它已经使用了刻度/纳秒 - 这意味着时间关闭并且不是每秒钟更长。 如果我可以按蜱或纳秒睡觉,它就会爆炸。

    如果数字1适用于System.Timers,那么我想我已经排序了。 如果不是,我需要某种方法将线程“睡眠”到更高的时间分辨率,即滴答/纳秒。

    您可能会问我为什么要使用内联IF语句,有时处理可能超过1000毫秒,因此我们需要确保不创建减号。此外,当我们确定这一点时,结束时间略有变化 - 不是很多,但是,它可能会使线程延迟稍长,导致整个后续休眠。

    我知道,我知道,时间可以忽略不计......但是如果系统突然停滞了几毫秒会发生什么......在这种情况下它可以防止这种情况。

    更新1

    确定。所以我没有意识到你可以把TimeSpan作为时间值。所以我使用了以下代码:

    Thread.Sleep(TimeSpan.FromMilliseconds(1000) - ((DateTime.Now.Subtract(start).TotalMilliseconds >= 1000) ? TimeSpan.FromMilliseconds(0) : DateTime.Now.Subtract(start)));
    

    如果我是对的,那么这应该允许我在1秒内重复该线程 - 或者在系统允许的时候尽可能接近。

1 个答案:

答案 0 :(得分:2)

如果您设置了AutoReset = true;,则理论1为真,否则您必须在代码中处理它 - 请参阅the docuementation for Timer on MSDN