场景:在 Winform 应用程序(C#)中,我有一个 Datagridview,我必须在其中显示 4 个倒数计时器,格式为“mm:ss”。时间间隔必须为 1000 毫秒。
我在 system.timers.timer 的经过事件中倒计时。
在所有 4 个计时器上,我从 2 分钟(02:00)开始倒计时。
问题:到达 00:00 需要超过 2 分钟的时间(125 秒)。同样 4 分钟,需要 7-10 多(247 -250)秒才能到达 00:00
系统上的计时器有点不准确。更好的系统通常会提供更好的计时器,但即使是最好的系统也会出现滑点。
您还需要记住,您的进程不会在 100% 的时间内处于“完全控制”状态,它有时会被推到后台,并且必须与其他应用程序共享处理器,因此尽管它会尽最大努力跟踪时间。
您可能想要的是 C# 中的高精度计时器(又名秒表)。查看这个线程和这篇关于选择计时器机制的文章以获取更多信息。
首先,您应该运行这个小测试并近乎实时地查看漂移。在 72 个计时器经过事件后,我失去了 1 秒(这几乎没有实际工作)。
using (var timer = new Timer(1000))
{
var start = DateTime.Now;
var i = 0;
timer.Elapsed += (sender, args) => Console.WriteLine("{0} -> {1}", ++i, (DateTime.Now - start).TotalMilliseconds);
timer.Start();
Thread.Sleep(130*1000);
}
我不确定您的应用程序需要多么精确,但您可以通过使用开始时间和现在之间的增量并从初始值中减去该增量并将计时器终止为零来获得“足够好”。 使用这种方法您将失去几秒钟,并且有合理的机会可能会发生失去的一秒钟@0:00
导致-0:01
滴答声,您需要处理。
var countdownSeconds = 120;
var startedAt = DateTime.Now;
var timer = new Timer(1000);
timer.Elapsed += (sender, args) => Display(countdownSeconds - (int)((DateTime.Now - startedAt).TotalSeconds));
timer.Start();
//- be sure to dispose the timer
如果您需要该类型的时间分辨率(即实际时钟或倒计时时钟),您应该使用实时时钟。
您仍然使用具有亚秒级分辨率的计时器来足够频繁地触发以用于显示目的,但是您不会将这些时间相加,而是使用实时时钟来获取实际经过的时间 ( DateTime.Now - startTime
)。