using System; using System.ComponentModel; using System.Runtime.InteropServices; using System.Threading; namespace Masuit.Tools.Systems; /// /// 高精度定时器,1ms精度 /// public class HighAccurateTimer : Disposable { private readonly long _clockFrequency; // result of QueryPerformanceFrequency() private bool _running; private Thread _timerThread; private int _intervalMs; // interval in mimliseccond; /// /// Timer inteval in milisecond /// public int Interval { get => _intervalMs; set { _intervalMs = value; _intevalTicks = (long)(value * (double)_clockFrequency / 1000); } } private long _intevalTicks; [DllImport("Kernel32.dll")] private static extern bool QueryPerformanceCounter(out long lpPerformanceCount); [DllImport("Kernel32.dll")] private static extern bool QueryPerformanceFrequency(out long lpFrequency); public HighAccurateTimer(int interval = 1) { if (QueryPerformanceFrequency(out _clockFrequency) == false) { // Frequency not supported throw new Win32Exception("QueryPerformanceFrequency() function is not supported"); } Interval = interval; } public bool GetTick(out long currentTickCount) { if (QueryPerformanceCounter(out currentTickCount) == false) throw new Win32Exception("QueryPerformanceCounter() failed!"); else return true; } public void Start(Action func) { _running = true; _timerThread = new Thread(() => { GetTick(out var currTime); var nextTriggerTime = currTime + _intevalTicks; // the time when next task will be executed while (_running) { while (currTime < nextTriggerTime) { GetTick(out currTime); } // wailt an interval nextTriggerTime = currTime + _intevalTicks; func(); } }) { Name = "HighAccuracyTimer", Priority = ThreadPriority.Highest }; _timerThread.Start(); } public void Stop() { _running = false; } ~HighAccurateTimer() { _running = false; } /// /// 释放 /// /// public override void Dispose(bool disposing) { Stop(); } }