高精度定时器的使用以及实现

一、高精度定时器的使用

1.添加引用,选择dll 文件

dll文件路径:

高精度定时器\MultimediaTimer\HighPrecisionTimer\bin\Debug\HighPrecisionTimer.dll

2.使用命名空间:

using HighPrecisionTimer;

3.使用定时器

    class Program
    {
        static readonly HPTimer timer = new HPTimer();//创建高精度定时器对象
        static DateTime lastTime;
        static void Main()
        {
            // 每秒执行一次
            timer.Interval = 1;//设置定时器的时间间隔
            timer.Ticked += Timer_Ticked;//timer的Ticked事件注册一个方法Timer_Ticked()
            lastTime = DateTime.Now;
            timer.Start();//高精度定时器开启

            Console.ReadKey();
            timer.Stop();//高精度定时器关闭
        }

        private static void Timer_Ticked()//Timer_Ticked方法
        {
            DateTime dateTime = DateTime.Now;
            TimeSpan tp = dateTime - lastTime;
            lastTime = dateTime;
            Console.WriteLine(tp.TotalMilliseconds);
        }
    }

二、高精度定时器的实现

1.创建一个项目,起名为HighPrecisionTimer;

2.在HighPrecisionTimer添加一个库文件EnumDefine.cs,该库文件的代码如下:

namespace HighPrecisionTimer
{
    public enum TimerError
    {
        /// <summary>没有错误</summary>
        MMSYSERR_NOERROR = 0,

        /// <summary>常规错误码</summary>
        MMSYSERR_ERROR = 1,
        /// <summary>ptc 为空,或 cbtc 无效,或其他错误</summary>
        TIMERR_NOCANDO = 97,
        /// <summary>无效参数</summary>
        MMSYSERR_INVALPARAM = 11,
    }

    public enum EventType01
    {
        /// <summary>单次执行</summary>
        TIME_ONESHOT = 0x0000,
        /// <summary>循环执行</summary>
        TIME_PERIODIC = 0x0001,
    }

    public enum EventType02
    {
        /// <summary>定时器到期时,调用回调方法。这是默认值</summary>
        TIME_CALLBACK_FUNCTION = 0x0000,
        /// <summary>定时器到期时,调用 setEvent</summary>
        TIME_CALLBACK_EVENT_SET = 0x0010,
        /// <summary>定时器到期时,调用 PulseEvent</summary>
        TIME_CALLBACK_EVENT_PULSE = 0x0020,
        /// <summary>防止在调用 timeKillEvent 函数之后发生事件</summary>
        TIME_KILL_SYNCHRONOUS = 0x0100,
    }
}

3.在HighPrecisionTimer添加一个库文件HPTimer.cs,该库文件的代码如下:

using System;
using System.Runtime.InteropServices;

namespace HighPrecisionTimer
{
    /// <summary>
    /// 定时器分辨率:毫秒
    /// </summary>
    struct TimerCaps
    {
        /// <summary>最小周期</summary>
        public int periodMin;
        /// <summary>最大周期</summary>
        public int periodMax;
    }

    /// <summary>
    /// 高精度定时器
    /// </summary>
    public class HPTimer
    {
        static HPTimer()
        {
            TimeGetDevCaps(ref _caps, Marshal.SizeOf(_caps));
        }

        public HPTimer()
        {
            Running = false;
            _interval = _caps.periodMin;
            _resolution = _caps.periodMin;
            _callback = new TimerCallback(TimerEventCallback);
        }

        ~HPTimer()
        {
            TimeKillEvent(_id);
        }

        /// <summary>
        /// 系统定时器回调
        /// </summary>
        /// <param name="id">定时器编号</param>
        /// <param name="msg">预留,不使用</param>
        /// <param name="user">用户实例数据</param>
        /// <param name="param1">预留,不使用</param>
        /// <param name="param2">预留,不使用</param>
        private delegate void TimerCallback(int id, int msg, int user, int param1, int param2);

        #region 动态库接口

        /// <summary>
        /// 查询设备支持的定时器分辨率
        /// </summary>
        /// <param name="ptc">定时器分辨率结构体指针</param>
        /// <param name="cbtc">定时器分辨率结构体大小</param>
        /// <returns></returns>
        [DllImport("winmm.dll", EntryPoint = "timeGetDevCaps")]
        private static extern TimerError TimeGetDevCaps(ref TimerCaps ptc, int cbtc);

        /// <summary>
        /// 绑定定时器事件
        /// </summary>
        /// <param name="delay">延时:毫秒</param>
        /// <param name="resolution">分辨率</param>
        /// <param name="callback">回调接口</param>
        /// <param name="user">用户提供的回调数据</param>
        /// <param name="eventType"></param>
        [DllImport("winmm.dll", EntryPoint = "timeSetEvent")]
        private static extern int TimeSetEvent(int delay, int resolution, TimerCallback callback, int user, int eventType);

        /// <summary>
        /// 终止定时器
        /// </summary>
        /// <param name="id">定时器编号</param>
        [DllImport("winmm.dll", EntryPoint = "timeKillEvent")]
        private static extern TimerError TimeKillEvent(int id);

        #endregion

        #region 属性

        /// <summary>时间间隔:毫秒</summary>
        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)
        {
            Ticked?.Invoke();
        }

        #endregion

        #region 字段

        // 系统定时器分辨率
        private static TimerCaps _caps;
        // 定时器间隔
        private int _interval;
        // 定时器分辨率
        private int _resolution;
        // 定时器回调
        private TimerCallback _callback;
        // 定时器编号
        private int _id;

        #endregion
    }
}

3.编译生成该项目,在bin目录下得到一个HighPrecisionTimer.dll文件。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值