C#/VB 计时器精确计时,关于Thread.Sleep(1),实际耗时15.6212ms的问题

摘要:

Thread.Sleep的精度默认在15ms左右,如果需要类似 Thread.Sleep(1)的精细控制,需要调用特定的平台API实现,通过引入winmm.dll库的MM_BeginPeriod和MM_EndPeriod函数来提高精度,使得Thread.Sleep(1)的耗时降低到接近0.8ms。通过调整时间间隔,可以减少耗时差异过大的情况。

调用WIN API中的winmm.dll

常用于多媒体定时器中,是返回操作系统启动到现在所经过的毫秒数,精度为1毫秒。

一般默认的精度不止1毫秒(不同操作系统有所不同),需要调用timeBeginPeriod与timeEndPeriod来设置精度

缺点:受返回值的最大位数限制。

C#:
//设置计时器分辨率, 单位毫秒(ms)
[DllImport("winmm.dll", EntryPoint = "timeBeginPeriod")]
public static extern uint MM_BeginPeriod(uint uMilliseconds);
//恢复计时器默认分辨率, 单位毫秒(ms)
[DllImport("winmm.dll", EntryPoint = "timeEndPeriod")]
public static extern uint MM_EndPeriod(uint uMilliseconds);
VB:
<DllImport("winmm.dll", EntryPoint:="timeBeginPeriod")>
Public Shared Function MM_BeginPeriod(ByVal uMilliseconds As UInteger) As UInteger
End Function
<DllImport("winmm.dll", EntryPoint:="timeEndPeriod")>
Public Shared Function MM_EndPeriod(ByVal uMilliseconds As UInteger) As UInteger
End Function

用法:

C#:
MM_BeginPeriod(1); DateTime start = DateTime.Now; Thread.Sleep(10); DateTime stop = DateTime.Now; TimeSpan timeInterval = stop - start; Console.WriteLine(timeInterval.TotalMilliseconds.ToString()); //单位毫秒 MM_EndPeriod(1);
VB:
MM_BeginPeriod(1)
Dim startTime As Date = Date.Now
Thread.Sleep(10)
Dim stopTime As Date = Date.Now
Dim timeInterval As TimeSpan = stopTime - startTime
Console.WriteLine(timeInterval.TotalMilliseconds.ToString())  '单位毫秒
MM_EndPeriod(1)

 

posted @ 2025-06-20 17:27  感冒药啊  阅读(111)  评论(0)    收藏  举报