c#每秒一个滴答声

c# each second a tick

我想编写一个程序,需要每秒获取一个滴答事件。 程序 运行 很多小时,滴答声必须与系统时钟的秒数一致。 使用每秒触发一个事件的任何类型的计时器都不是一个好主意。有很多不准确之处。 如果每秒有 100 毫秒的误差,则计时器每小时比系统时钟慢 6 减。 但是,它必须与系统时钟完全一致。

从系统时钟获取事件是可以的。

一秒钟不准确是可以的,但不是全部。

你有什么解决这个问题的建议?

解决方案必须在 c# net6 上运行(我计划 运行 Windows 和 Linux 上的程序)。

谢谢

如果准确性是个问题,并且您不喜欢引发事件的计时器的准确性,那么一个简单的解决方法是使用轮询方法。

我并不是说这很有效,你会希望确保你为每个 tick 执行的任务比你想要发射的单位在更短的时间内完成on,所以在这种情况下是一秒钟,但它满足了与系统时钟紧密绑定的要求:

Action tickAction = () => Console.WriteLine(DateTime.Now);
int lastTick = DateTime.Now.TimeOfDay.Seconds;
while (true)
{
    var seconds = DateTime.Now.TimeOfDay.Seconds;
    if(lastTick != seconds)
    {
        lastTick = seconds;
        tickAction();
    }
}

您也可以在每个动作之后启动一个计时器,其延迟等于下一秒剩余的刻度数,但那是因为 1 秒计时器有点矫枉过正。但是,如果时间间隔是可变的,或者执行操作所花费的时间可能超过下一个 window,那么以基于计时器的方式执行此操作可能就足够有意义了。

Overall the event processing loop and whatever else is going on in the background can affect the accuracy even of this solution, having more context on the action that you want to execute on each second would be helpful to produce a more commercially viable solution.

这会让你在时钟的每一秒后 0..20 毫秒内到达。

static System.Threading.Timer timer = new(CallBack, null, 0, 0);

static void CallBack(object? state)
{
  var now = DateTime.Now;
  timer.Change(1000 - now.Millisecond, 0);

  // Console.WriteLine(now + " " + now.Millisecond);
}