[.NET] 如何用C#做高精度计时器

简介

这篇文章是说明如何使用C#做高精度的计时器,有些时候,我们会需要用到精准度更高的计时器及Sleep,但Sleep的精准度并不高

因此只好自己客制化了

 

背景

 

在一般的系统中,Sleep(1)其实是相当于15.625ms(1/64秒),也就是说Sleep(15)以下都是Sleep一样的时间.

微软MSDN参考资料

 

源码

 

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

 

说明

 

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

 

QueryPerformanceCounter:可以取得CPU运行到现在的Tick数

 

在这个程式范例中,我自行写了一个AccurateSleep,这个函数的目的是因为Sleep的精准度只有15.625毫秒

如果只有计时器精准,但是Sleep却不精准,那怎么样也无法测出15.625毫秒以下的精准度

但是如果仅用while loop做等待,那却会造成程式无回应,因此在回圈中,需要再处理Windows的讯息,避免程式无回应

 

参考资料

你可能感兴趣的:(.net,windows,struct,C#,Class,performance)