Windows高速定時器,多媒體定時器winmm.dll庫的使用

來源:互聯網
上載者:User

標籤:value   event   事件   use   images   回呼函數   利用   key   extern   

項目裡面用到的這些看起來名字高大上的定時器測試下來也是非常不準。看了源碼發現也是用System.Timers.Timer或者用的是Thread休眠的方式來實現的。100毫秒就不準了。直到一番搜尋,發現利用多媒體定時器winmm.dll的MillisecondTimer是可用的。原文來自部落格(dehai)Timer計時不準確的問題及解決方案”。代碼如下:

 public sealed class MillisecondTimer : IComponent, IDisposable    {        //*****************************************************  字 段  *******************************************************************        private static TimerCaps caps;        private int interval;        private bool isRunning;        private int resolution;        private TimerCallback timerCallback;        private int timerID;        //*****************************************************  屬 性  *******************************************************************        /// <summary>        ///         /// </summary>        public int Interval        {            get            {                return this.interval;            }            set            {                if ((value < caps.periodMin) || (value > caps.periodMax))                {                    throw new Exception("超出計時範圍!");                }                this.interval = value;            }        }        /// <summary>        ///         /// </summary>        public bool IsRunning        {            get            {                return this.isRunning;            }        }        /// <summary>        ///         /// </summary>        public ISite Site        {            set;            get;        }        //*****************************************************  事 件  *******************************************************************        public event EventHandler Disposed;  // 這個事件實現了IComponet介面        public event EventHandler Tick;        //***************************************************  建構函式和釋構函數  ******************************************************************        static MillisecondTimer()        {            timeGetDevCaps(ref caps, Marshal.SizeOf(caps));        }        public MillisecondTimer()        {            this.interval = caps.periodMin;    //             this.resolution = caps.periodMin;  //            this.isRunning = false;            this.timerCallback = new TimerCallback(this.TimerEventCallback);        }        public MillisecondTimer(IContainer container)            : this()        {            container.Add(this);        }        ~MillisecondTimer()        {            timeKillEvent(this.timerID);        }        //*****************************************************  方 法  *******************************************************************        /// <summary>        ///         /// </summary>        public void Start()        {            if (!isRunning)            {                timerID = timeSetEvent(this.interval, this.resolution, this.timerCallback, 0, 1); // 間隔性地運行                if (timerID == 0)                {                    throw new Exception("無法啟動計時器");                }                isRunning = true;            }        }        /// <summary>        ///         /// </summary>        public void Stop()        {            if (isRunning)            {                timeKillEvent(this.timerID);                isRunning = false;            }        }        /// <summary>        /// 實現IDisposable介面        /// </summary>        public void Dispose()        {            timeKillEvent(this.timerID);            GC.SuppressFinalize(this);            Disposed?.Invoke(this, EventArgs.Empty);        }        //***************************************************  內建函式  ******************************************************************        [DllImport("winmm.dll")]        private static extern int timeSetEvent(int delay, int resolution, TimerCallback callback, int user, int mode);        [DllImport("winmm.dll")]        private static extern int timeKillEvent(int id);        [DllImport("winmm.dll")]        private static extern int timeGetDevCaps(ref TimerCaps caps, int sizeOfTimerCaps);         private void TimerEventCallback(int id, int msg, int user, int param1, int param2)        {            Tick?.Invoke(this, null);  // 引發事件        }        //***************************************************  內部類型  ******************************************************************        private delegate void TimerCallback(int id, int msg, int user, int param1, int param2); // timeSetEvent所對應的回呼函數的簽名        /// <summary>        /// 定時器的解析度(resolution)。單位是ms,毫秒?        /// </summary>        [StructLayout(LayoutKind.Sequential)]        private struct TimerCaps        {            public int periodMin;            public int periodMax;        }    }}
測試代碼
 class Program    {        static Dictionary<string, int> dtList = new Dictionary<string, int>();        static void Main(string[] args)        {            //var timer = new DoubleThreadTimer(100, 100);            //timer.OnRunningCallback += Timer1_Tick;            //timer.Start();            var timer1 = new MillisecondTimer();            timer1.Interval = 2;            timer1.Tick += Timer1_Tick;            timer1.Start();            Console.ReadLine();        }        private static void Timer1_Tick(object sender, EventArgs e)        {            var dt = DateTime.Now;            string dtStr = dt.ToString("yyyyMMdd HHmmss");            if (dtList.ContainsKey(dtStr))            {                dtList[dtStr]++;                if (dtList[dtStr] % 500 == 0)                {                                        Console.WriteLine(dtStr + "--->" + dtList[dtStr]);                    dtList.Remove(dtStr);                }             }            else            {                if (dtList.Count > 1)                {                    foreach (var item in dtList)                    {                        Console.WriteLine(item.Key + "--->" + item.Value);                     }                    dtList.Clear();                }                dtList.Add(dtStr, 1);                            }        }    }

  

測試結論: 時間間隔設定為5毫秒,表現很穩定。2毫秒有時准。可靠性比.net的timer准好多倍啊

 

Windows高速定時器,多媒體定時器winmm.dll庫的使用

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.