using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace MECF.Framework.Common.Utilities { /// /// 定时器分辨率:毫秒 /// struct TimerCaps { /// 最小周期 public int periodMin; /// 最大周期 public int periodMax; } /// /// 高精度定时器 /// public class MMTimer { static MMTimer() { TimeGetDevCaps(ref _caps, Marshal.SizeOf(_caps)); } public MMTimer() { Running = false; _interval = _caps.periodMin; _resolution = _caps.periodMin; _callback = new TimerCallback(TimerEventCallback); } ~MMTimer() { TimeKillEvent(_id); } /// /// 系统定时器回调 /// /// 定时器编号 /// 预留,不使用 /// 用户实例数据 /// 预留,不使用 /// 预留,不使用 private delegate void TimerCallback(int id, int msg, int user, int param1, int param2); #region 动态库接口 /// /// 查询设备支持的定时器分辨率 /// /// 定时器分辨率结构体指针 /// 定时器分辨率结构体大小 /// [DllImport("winmm.dll", EntryPoint = "timeGetDevCaps")] private static extern TimerError TimeGetDevCaps(ref TimerCaps ptc, int cbtc); /// /// 绑定定时器事件 /// /// 延时:毫秒 /// 分辨率 /// 回调接口 /// 用户提供的回调数据 /// [DllImport("winmm.dll", EntryPoint = "timeSetEvent")] private static extern int TimeSetEvent(int delay, int resolution, TimerCallback callback, int user, int eventType); /// /// 终止定时器 /// /// 定时器编号 [DllImport("winmm.dll", EntryPoint = "timeKillEvent")] private static extern TimerError TimeKillEvent(int id); #endregion #region 属性 /// 时间间隔:毫秒 public int Interval { get { return _interval; } set { if (value < _caps.periodMin || value > _caps.periodMax) throw new Exception("无效的计时间隔"); _interval = value; } } public bool Running { get; private set; } #endregion #region 事件 public event Action Ticked; #endregion #region 公开方法 public void Start() { if (!Running) { _id = TimeSetEvent(_interval, _resolution, _callback, 0, (int)EventType01.TIME_PERIODIC | (int)EventType02.TIME_KILL_SYNCHRONOUS); if (_id == 0) throw new Exception("启动定时器失败"); Running = true; } } public void Stop() { if (Running) { TimeKillEvent(_id); Running = false; } } #endregion #region 内部方法 private void TimerEventCallback(int id, int msg, int user, int param1, int param2) { try { Ticked?.Invoke(); } catch { throw; } } #endregion #region 字段 // 系统定时器分辨率 private static TimerCaps _caps; // 定时器间隔 private int _interval; // 定时器分辨率 private int _resolution; // 定时器回调 private TimerCallback _callback; // 定时器编号 private int _id; #endregion } public enum TimerError { /// 没有错误 MMSYSERR_NOERROR = 0, /// 常规错误码 MMSYSERR_ERROR = 1, /// ptc 为空,或 cbtc 无效,或其他错误 TIMERR_NOCANDO = 97, /// 无效参数 MMSYSERR_INVALPARAM = 11, } public enum EventType01 { /// 单次执行 TIME_ONESHOT = 0x0000, /// 循环执行 TIME_PERIODIC = 0x0001, } public enum EventType02 { /// 定时器到期时,调用回调方法。这是默认值 TIME_CALLBACK_FUNCTION = 0x0000, /// 定时器到期时,调用 setEvent TIME_CALLBACK_EVENT_SET = 0x0010, /// 定时器到期时,调用 PulseEvent TIME_CALLBACK_EVENT_PULSE = 0x0020, /// 防止在调用 timeKillEvent 函数之后发生事件 TIME_KILL_SYNCHRONOUS = 0x0100, } }