.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只需在构造函数进行即可