微软官方说明,win7以上系统,Timer的及时精度有15ms误差。
故,这里有个Case,比如我们项维持一个程序内时间,在Timer定时1000ms,在Elaspe内,做DateTime.AddSecond(1),那么这个时间就不再准确,没1000ms有15ms误差。
没一分钟有1秒误差,实际测试每5分钟有2秒误差。所以,我们如果要程序每秒定期激发,需要自己写一个方法。
/// <summary>
/// 作为精确定时器的每秒激发事件
/// <para>SystemTimer的每1000ms有大约15ms误差的问题。</para>
/// </summary>
public class AccuTimer
{
private System.Threading.Thread backThread;
/// <summary>
/// 每秒激发事件
/// </summary>
public event Action ElapsedPreSecond;
/// <summary>
/// 是否可用
/// </summary>
public bool Enable = true;
/// <summary>
/// 开始
/// </summary>
public void Start()
{
Enable = true;
if (backThread == null)
{
backThread = new System.Threading.Thread(InnerLoop);
backThread.IsBackground = true;
backThread.Start();
}
}
/// <summary>
/// 停止
/// </summary>
public void Stop()
{
Enable = false;
}
private void InnerLoop()
{
DateTime preTime = DateTime.Now;
while (true)
{
try
{
//每当秒数变化即激发事件
DateTime curTime = DateTime.Now;
if (Math.Abs(curTime.Second - preTime.Second + 60) % 60 >= 1)
{
preTime = curTime;
if (Enable && ElapsedPreSecond != null)
{
System.Threading.ThreadPool.QueueUserWorkItem(o =>
{
ElapsedPreSecond.Invoke();
});
}
}
}
catch
{
}
finally
{
//尽量小的间隔去监视秒数变化
System.Threading.Thread.Sleep(50);
}
}
}
}