我对计时器有一个奇怪的问题。据我所知,计时器的间隔属性表示将触发 timer_Tick 事件的循环之间的延迟。
在使用 Visual Basic 编程之前,我遇到了精确签名(15 和 16 毫秒延迟)的问题。我创建的任何计时器都会以 15 或 16 毫秒的延迟触发它们的滴答事件。例如,如果我将计时器的间隔设置为 1(这意味着它的滴答事件应该在 1 秒内触发 1000 次),则该事件会在 1 秒内触发 62 到 66 次(即 1000/16 到 1000/15 )。
我从 5 年前开始开发 VB 应用程序并且一直遇到这个问题(这也意味着我在使用 AMD 和 Intel 处理器的几个不同系统上遇到了这个问题),现在我又在 C# 中遇到了这个问题。
我设法通过基于 TickCount 方法(VB 中的 GetTickCount API 和 C# 中的 Environment.TickCount)计算每次触发滴答事件之间的时间差来解决此问题。
*TickCount 是自系统启动以来经过的毫秒数。
为了更好地理解这个问题,我创建了一个 Windows 应用程序,它计算自执行以来的秒数(如计时器)。每次触发 Tick 事件时,它都依赖于 TickCount 和普通加法。它还通过从 TickCount 的当前值中减去 TickCount 的最后一个值来计算计时器的延迟(如果计时器确实在 1 秒内被触发了 1000 次,那么每次 TickCounts 的差值将是 1,因此意味着没有延迟,但如果差值大于 1,则每次触发计时器的滴答事件之间会有一些延迟)。
这是代码:
public partial class Form1 : Form
{
int localTime = 0, systemTime = 0, baseSystemTime = 0, lastSystemTime = 0;
public Form1()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
// Calculate time based on TickCount
if (baseSystemTime == 0)
baseSystemTime = Environment.TickCount;
systemTime = Environment.TickCount - baseSystemTime;
label2.Text ="System Time: " + ((systemTime / 1000) / 60).ToString() + ":" + ((systemTime / 1000) % 60).ToString();
// Calculate time based on timer1_Tick
localTime++;
label1.Text = "Application Time: " + ((localTime / 1000) / 60).ToString() + ":" + ((localTime / 1000) % 60).ToString();
// Calculate the delay
if (lastSystemTime > 0)
{
label3.Text = "Delay: " + (Environment.TickCount - lastSystemTime).ToString() + " ms";
}
lastSystemTime = Environment.TickCount;
}
}
我还在这里上传了整个解决方案:http ://ramt.in/test/TimerDelay.zip
这是应用程序的屏幕截图(延迟 15 毫秒,应用程序计算 1 秒,而实际上已经过去了 17 秒!):
该解决方案只有 50kb,所以请随意下载并运行它,看看您是否得到与我相同的结果。如果相同,那么微软世界的计时器类有问题!
但更重要的是,如果有人知道可能导致此延迟的原因,请与我分享您的知识。