【问题标题】:C# timer start at exact full secondC# 计时器以整秒开始
【发布时间】:2017-03-07 14:03:20
【问题描述】:

有没有办法运行Timer,让它在整秒开始?

stateTimer = new Timer(someCallback, null, 0, 1000);

这将立即启动,每秒重复一次,但问题是它会在我运行程序时准确启动,这可能导致13:14:15.230 启动。

我想13:14:15.000 开始。比如:

stateTimer = new Timer(someCallback, null, DateTime.Now.Date, 1000);

这可能吗?

编辑:

做完控制台日志:

Console.WriteLine($"Time: {DateTime.Now.ToString("HH:mm:ss.fff")}");

我注意到 1 秒间隔实际上增加了超过一秒(每次迭代大约 1,02 次),因此在 50 次迭代后跳过了一秒。我通过让计时器每 800 毫秒运行一次来​​解决我的问题。不是理想的解决方案,但它有效,并且永远不会跳过第二个(而且我两次触发相同的第二个没有问题)。

stateTimer = new Timer(someCallback, null, 0, 800);

【问题讨论】:

  • 如果计时器没有准确地在第二个运行,为什么会出现问题?
  • 你可以计算下一次你想要启动它并休眠那么久的时间,然后启动它,但要注意 Windows 不是实时操作系统,它不能保证您的计时器将准确地按照您指定的时间间隔滴答作响,仅“足够接近”。为什么需要这样精确?
  • 没有小数部分的“秒”是一个虚构的或理论上的概念,它完全是任意的。一个人(或计算机)认为是精确/整秒,另一个人认为是在两秒的中间,因为不可能使两者同步。除非你能解释为什么这对你来说是必要或有用的,否则这个问题没有价值。
  • 假设这是可能的,并且处理程序恰好在那个时间开始运行。是什么阻止了操作系统在那一刻切换到另一个线程 16 毫秒?没有。因此,即使可以做你想做的事,但事实并非如此,你仍然会遇到同样的问题。

标签: c# timer


【解决方案1】:

不,那是不可能的。这将要求您准确地知道 CPU 认为何时开始执行您的计时器代码是一个好主意。即使你在剩下的时间里Thread.Sleep,它仍然不意味着代码会在你想要的毫秒内执行。

相反,如果您只想为格式化执行此操作,您可以使用自定义日期/时间格式来执行此操作。

【讨论】:

    【解决方案2】:

    我必须在一个显示时间并显示分钟和秒数的程序中做类似的事情,直到用户可以做某事。

    原始代码使用 1000 毫秒计时器。这有原始海报描述的问题。我创建了一个线程。线程有一个循环:

    private ManualResetEvent myThreadRequestExit = new ManualResetEvent(false);
    
    while (!myThreadRequestExit.WaitOne(1000 - DateTime.UtcNow.Millisecond))
    {
        // Do the one-second work here
    }
    

    设置 MyThreadRequestExit 时,循环将退出,线程将终止。

    虽然它可能会在第二秒开始后几毫秒触发,但它足够接近,以至于用户认为计时器应该在滴答作响,并且只要工作可以在不到一秒的时间内完成,它就不会丢失秒数.

    【讨论】:

      猜你喜欢
      • 2021-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-08
      相关资源
      最近更新 更多