C# 定时器精确到毫秒并对其进行误差测试

    技术2022-05-20  40

    .Net里面的System.Windows.Forms.Timer,当设置其Interval到毫秒级别(<1000)时,会出现令人咋舌的误差,而且有两方面会使误差进一步拉大1、Interval设的越小,误差越大;2、随着定时器工作时间的推移,误差也越大下面是一段Demo测试代码,仅供参考:

    namespace MyTimerDemo { public partial class Form1 : Form { #region 私有变量 定义 /// <summary> /// 记录每次启动定时器的时间 /// </summary> private DateTime startTime; /// <summary> /// 定时器已走时间 /// </summary> private TimeSpan span; /// <summary> /// 记录每次暂停时定时器已走时间 /// </summary> private TimeSpan pauseSpan; /// <summary> /// 时间(秒) /// </summary> private int time; /// <summary> /// 是否倒计时 /// </summary> private bool bDown; /// <summary> /// 误差测试临时变量 /// </summary> private int iCount = 0; #endregion public Form1() { InitializeComponent(); timer1.Interval = 1; //每毫秒执行一次 time = 0; //初始化时间 //倒计时设定,如果时间为0则正计时,否则倒计时 if (time == 0) { bDown = false; } else { bDown = true; } label1.Text = string.Format("00:00:{0}:000", time.ToString("00")); label2.Text = time.ToString("00"); } /// <summary> /// 开始/暂停 /// </summary> private void btnStartPause_Click(object sender, EventArgs e) { timer1.Enabled = !timer1.Enabled; if (timer1.Enabled) //开始 { btnStartPause.Text = "Pause"; //启动定时器,务必修改启动时间 startTime = DateTime.Now; } else //暂停 { btnStartPause.Text = "Start"; //暂停,记录定时器当前已走时间 pauseSpan = span; } } /// <summary> /// 停止定时器 /// </summary> private void btnStop_Click(object sender, EventArgs e) { timer1.Enabled = false; btnStartPause.Enabled = true; btnStartPause.Text = "Start"; pauseSpan = new TimeSpan(0); //将上次暂停 记录的已走时间清零 label1.Text = string.Format("00:00:{0}:000", time.ToString("00")); label2.Text = time.ToString("00"); } private void timer1_Tick(object sender, EventArgs e) { //刷新定时器已走时间 //注意务必加上 上次暂停记录的已走时间 span = (DateTime.Now - startTime).Add(pauseSpan); if (bDown) //倒计时 { //若时间倒到0,定时器停止工作 if (span.Ticks >= time * TimeSpan.TicksPerSecond) { btnStartPause.Enabled = false; timer1.Enabled = false; } else { DateTime spanDt = new DateTime( time * TimeSpan.TicksPerSecond - span.Ticks); label1.Text = spanDt.ToString("HH:mm:ss:fff"); label2.Text = (time - span.TotalSeconds).ToString("00"); } } else //正计时 { DateTime spanDt = new DateTime(span.Ticks); label1.Text = spanDt.ToString("HH:mm:ss:fff"); label2.Text = span.TotalSeconds.ToString("00"); //误差测试,在正计时进行 --> 简单、方便:) iCount += timer1.Interval; label3.Text = (iCount / 1000).ToString("00"); } } } }

     

    修改Interval只需在构造函数进行即可

     


    最新回复(0)