计时器最小限制

本文关键字:计时器 | 更新日期: 2023-09-27 17:56:19

我需要编写一个程序(.NET C#)来做一些事情,但每0.5毫秒我需要读取一些数据,看看它是否更改为某个值或高于它,如果该值已达到该目标,请停止我正在做的其他一切。将计时器设置为每 0.5 毫秒运行一次是否有问题?这种程序的正确方法是什么?

计时器最小限制

1 毫秒还是 0.5 毫秒?

汉斯是对的,多媒体定时器接口能够提供低至1毫秒的分辨率。有关timeBeginPeriod的详细信息,请参阅关于多媒体计时器 (MSDN)、获取和设置计时器分辨率 (MSDN) 和此答案。注意:不要忘记调用 timeEndPeriod 以在完成后切换回默认计时器分辨率。

怎么做:

#define TARGET_RESOLUTION 1         // 1-millisecond target resolution
TIMECAPS tc;
UINT     wTimerRes;
if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) 
{
   // Error; application can't continue.
}
wTimerRes = min(max(tc.wPeriodMin, TARGET_RESOLUTION), tc.wPeriodMax);
timeBeginPeriod(wTimerRes); 
// do your stuff here at approx. 1 ms timer resolution
timeEndPeriod(wTimerRes); 

注意:此过程也适用于其他进程,并且获得的分辨率适用于系统范围。任何进程要求的最高分辨率都将处于活动状态,请注意后果。

但是,您可以通过隐藏的 API NtSetTimerResolution()获得 0.5 毫秒的分辨率。 NtSetTimerResolution由本机 Windows NT 库 NTDLL.DLL 导出。请参阅如何将定时器分辨率设置为 0.5ms ?在 MSDN 上。然而,真正可实现的分辨率取决于底层硬件。现代硬件确实支持 0.5 毫秒的分辨率。更多细节可以在Windows NT高分辨率计时器中找到。

怎么做:

#define STATUS_SUCCESS 0
#define STATUS_TIMER_RESOLUTION_NOT_SET 0xC0000245
// after loading NtSetTimerResolution from ntdll.dll:
ULONG RequestedResolution = 5000;
ULONG CurrentResolution = 0;
// 1. Requesting a higher resolution
if (NtSetTimerResolution(RequestedResolution,TRUE,&CurrentResolution) != STATUS_SUCCESS) {
    // The call has failed
}
printf("CurrentResolution [100 ns units]: %d'n",CurrentResolution);
// this will show 5000 on more modern platforms (0.5ms!)
// do your stuff here at 0.5 ms timer resolution
// 2. Releasing the requested resolution
switch (NtSetTimerResolution(RequestedResolution,FALSE,&CurrentResolution) {
    case STATUS_SUCCESS:
        printf("The current resolution has returned to %d [100 ns units]'n",CurrentResolution);
        break;
    case STATUS_TIMER_RESOLUTION_NOT_SET:
        printf("The requested resolution was not set'n");   
        // the resolution can only return to a previous value by means of FALSE 
        // when the current resolution was set by this application      
        break;
    default:
        // The call has failed
}

注意:NtSetTimerResolution的功能基本上映射到函数timeBeginPeriod并使用布尔值Set timeEndPeriod(有关该方案及其所有含义的更多详细信息,请参阅 Windows NT 高分辨率计时器内部)。但是,多媒体套件将粒度限制为毫秒,NtSetTimerResolution允许设置亚毫秒值。

您可以使用MicroLibrary来实现此目的。看看: http://www.codeproject.com/Articles/98346/Microsecond-and-Millisecond-NET-Timer