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,
}
}