通常winform自带的三种定时器就足够用了,但是在某些场合,还存在着精度低,10ms以下不准的问题,现在推荐这款微秒级别的定时器
using System; namespace MicroLibrary { /// <summary> /// MicroStopwatch class /// </summary> public class MicroStopwatch : System.Diagnostics.Stopwatch { readonly double _microSecPerTick = 1000000D / System.Diagnostics.Stopwatch.Frequency; public MicroStopwatch() { if (!System.Diagnostics.Stopwatch.IsHighResolution) { throw new Exception("On this system the high-resolution " + "performance counter is not available"); } } public long ElapsedMicroseconds { get { return (long)(ElapsedTicks * _microSecPerTick); } } } /// <summary> /// MicroTimer class /// </summary> public class MicroTimer { public delegate void MicroTimerElapsedEventHandler( object sender, MicroTimerEventArgs timerEventArgs); public event MicroTimerElapsedEventHandler MicroTimerElapsed; System.Threading.Thread _threadTimer = null; long _ignoreEventIfLateBy = long.MaxValue; long _timerIntervalInMicroSec = 0; bool _stopTimer = true; public MicroTimer() { } public MicroTimer(long timerIntervalInMicroseconds) { Interval = timerIntervalInMicroseconds; } public long Interval { get { return System.Threading.Interlocked.Read( ref _timerIntervalInMicroSec); } set { System.Threading.Interlocked.Exchange( ref _timerIntervalInMicroSec, value); } } public long IgnoreEventIfLateBy { get { return System.Threading.Interlocked.Read( ref _ignoreEventIfLateBy); } set { System.Threading.Interlocked.Exchange( ref _ignoreEventIfLateBy, value <= 0 ? long.MaxValue : value); } } public bool Enabled { set { if (value) { Start(); } else { Stop(); } } get { return (_threadTimer != null && _threadTimer.IsAlive); } } public void Start() { if (Enabled || Interval <= 0) { return; } _stopTimer = false; System.Threading.ThreadStart threadStart = delegate() { NotificationTimer(ref _timerIntervalInMicroSec, ref _ignoreEventIfLateBy, ref _stopTimer); }; _threadTimer = new System.Threading.Thread(threadStart); _threadTimer.Priority = System.Threading.ThreadPriority.Highest; _threadTimer.Start(); } public void Stop() { _stopTimer = true; } public void StopAndWait() { StopAndWait(System.Threading.Timeout.Infinite); } public bool StopAndWait(int timeoutInMilliSec) { _stopTimer = true; if (!Enabled || _threadTimer.ManagedThreadId == System.Threading.Thread.CurrentThread.ManagedThreadId) { return true; } return _threadTimer.Join(timeoutInMilliSec); } public void Abort() { _stopTimer = true; if (Enabled) { _threadTimer.Abort(); } } void NotificationTimer(ref long timerIntervalInMicroSec, ref long ignoreEventIfLateBy, ref bool stopTimer) { int timerCount = 0; long nextNotification = 0; MicroStopwatch microStopwatch = new MicroStopwatch(); microStopwatch.Start(); while (!stopTimer) { long callbackFunctionExecutionTime = microStopwatch.ElapsedMicroseconds - nextNotification; long timerIntervalInMicroSecCurrent = System.Threading.Interlocked.Read(ref timerIntervalInMicroSec); long ignoreEventIfLateByCurrent = System.Threading.Interlocked.Read(ref ignoreEventIfLateBy); nextNotification += timerIntervalInMicroSecCurrent; timerCount++; long elapsedMicroseconds = 0; while ( (elapsedMicroseconds = microStopwatch.ElapsedMicroseconds) < nextNotification) { System.Threading.Thread.SpinWait(10); } long timerLateBy = elapsedMicroseconds - nextNotification; if (timerLateBy >= ignoreEventIfLateByCurrent) { continue; } MicroTimerEventArgs microTimerEventArgs = new MicroTimerEventArgs(timerCount, elapsedMicroseconds, timerLateBy, callbackFunctionExecutionTime); MicroTimerElapsed(this, microTimerEventArgs); } microStopwatch.Stop(); } } /// <summary> /// MicroTimer Event Argument class /// </summary> public class MicroTimerEventArgs : EventArgs { // Simple counter, number times timed event (callback function) executed public int TimerCount { get; private set; } // Time when timed event was called since timer started public long ElapsedMicroseconds { get; private set; } // How late the timer was compared to when it should have been called public long TimerLateBy { get; private set; } // Time it took to execute previous call to callback function (OnTimedEvent) public long CallbackFunctionExecutionTime { get; private set; } public MicroTimerEventArgs(int timerCount, long elapsedMicroseconds, long timerLateBy, long callbackFunctionExecutionTime) { TimerCount = timerCount; ElapsedMicroseconds = elapsedMicroseconds; TimerLateBy = timerLateBy; CallbackFunctionExecutionTime = callbackFunctionExecutionTime; } } }
使用方法
private readonly MicroLibrary.MicroTimer _microTimer; public MainView() { InitializeComponent(); _microTimer = new MicroLibrary.MicroTimer(); _microTimer.MicroTimerElapsed += new MicroLibrary.MicroTimer.MicroTimerElapsedEventHandler(OnTimedEvent); } private void button1_Click(object sender, EventArgs e) { Image bitmap = Image.FromFile("test.jpg"); pictureBox1.Image = bitmap; pictureBox1.Height = bitmap.Height; panel1.Height = bitmap.Height; //_sysTimer = new MillisecondTimer(); //_sysTimer.Tick += sysTimer_Tick; ; //_sysTimer.Interval = 10; //每秒执行 //_sysTimer.Start(); // Set timer interval long interval=1000;//1毫秒 _microTimer.Interval = interval; // Ignore event if late by half the interval _microTimer.IgnoreEventIfLateBy = interval / 2; // Start timer _microTimer.Start(); } private void OnTimedEvent(object sender, MicroLibrary.MicroTimerEventArgs timerEventArgs) { // Do something small that takes significantly less time than Interval. // BeginInvoke executes on the UI thread but this calling thread does not // wait for completion before continuing (i.e. it executes asynchronously) if (InvokeRequired) { BeginInvoke((MethodInvoker)delegate { //需要定时执行的内容 int locationY = panel1.Location.Y; locationY--; this.Invoke((EventHandler)delegate { panel1.Location = new Point(panel1.Location.X, locationY); }); }); } }
文章评论