[.NET] 如何用C#做高精度計時器

來源:互聯網
上載者:User

簡介

這篇文章是說明如何使用C#做高精度的計時器,有些時候,我們會需要用到精準度更高的計時器及Sleep,但Sleep的精準度並不高

因此只好自己客制化了

 

背景

 

在一般的系統中,Sleep(1)其實是相當於15.625ms(1/64秒),也就是說Sleep(15)以下都是Sleep一樣的時間.

微軟MSDN參考資料

 

源碼

 

[StructLayout(LayoutKind.Sequential)]<br />public struct MSG<br />{<br /> public IntPtr handle;<br /> public uint msg;<br /> public IntPtr wParam;<br /> public IntPtr lParam;<br /> public uint time;<br /> public System.Drawing.Point p;<br />}<br />public class AccurateTimer<br />{<br /> public static bool IsTimeBeginPeriod = false;</p><p> const int PM_REMOVE = 0x0001;</p><p> [DllImport("kernel32.dll", SetLastError = true)]<br /> static extern bool PeekMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin,<br /> uint wMsgFilterMax, uint wRemoveMsg);</p><p> [DllImport("kernel32.dll", SetLastError = true)]<br /> static extern bool TranslateMessage(ref MSG lpMsg);</p><p> [DllImport("kernel32.dll", SetLastError = true)]<br /> static extern bool DispatchMessage(ref MSG lpMsg);</p><p> [DllImport("kernel32.dll", SetLastError = true)]<br /> public static extern bool QueryPerformanceCounter(ref Int64 count);</p><p> [DllImport("kernel32.dll", SetLastError = true)]<br /> public static extern bool QueryPerformanceFrequency(ref Int64 frequency);</p><p> public static int GetTimeTick()<br /> {<br /> return Environment.TickCount;<br /> }</p><p> public static void AccurateSleep(int a_i4MSec)<br /> {<br /> Int64 t_i8Frequency = 0;<br /> Int64 t_i8StartTime = 0;<br /> Int64 t_i8EndTime = 0;<br /> double t_r8PassedMSec = 0;<br /> MSG msg;<br /> AccurateTimer.QueryPerformanceCounter(ref t_i8StartTime);<br /> AccurateTimer.QueryPerformanceFrequency(ref t_i8Frequency);<br /> do<br /> {<br /> if (AccurateTimer.PeekMessage(out msg, IntPtr.Zero, 0, 0, PM_REMOVE))<br /> {<br /> AccurateTimer.TranslateMessage(ref msg);<br /> AccurateTimer.DispatchMessage(ref msg);<br /> }<br /> AccurateTimer.QueryPerformanceCounter(ref t_i8EndTime);<br /> t_r8PassedMSec = ((double)(t_i8EndTime - t_i8StartTime) / (double)t_i8Frequency) * 1000;<br /> } while (t_r8PassedMSec <= a_i4MSec);<br /> }<br />}

 

說明

 

QueryPerformanceFrequency:可以取得每秒CPU的Performance Tick

 

QueryPerformanceCounter:可以取得CPU運行到現在的Tick數

 

在這個程式範例中,我自行寫了一個AccurateSleep,這個函數的目的是因為Sleep的精準度只有15.625毫秒

如果只有計時器精準,但是Sleep卻不精準,那怎麼樣也無法測出15.625毫秒以下的精準度

但是如果僅用while loop做等待,那卻會造成程式無回應,因此在迴圈中,需要再處理Windows的訊息,避免程式無回應

 

參考資料

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.