我需要编写一个程序(.NET C#),它正在做一些事情,但每0.5毫秒我需要读取一些数据并查看它是否已更改为某个值或更高,如果该值已达到该目标,停止我正在做的其他事情。 设置定时器每0.5毫秒运行一次有问题吗? 这类计划的正确方法是什么?
答案 0 :(得分:3)
汉斯是对的,多媒体计时器接口能够提供低至1毫秒的分辨率。
有关timeBeginPeriod
的详细信息,请参阅About Multimedia Timers(MSDN),Obtaining and Setting Timer Resolution(MSDN)和this答案。注意:完成后,请不要忘记调用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 ms 分辨率。
NtSetTimerResolution
由本机Windows NT库NTDLL.DLL导出。请参阅MSDN上的How to set timer resolution to 0.5ms ?。然而,真正可实现的分辨率由底层硬件决定。现代硬件支持0.5毫秒的分辨率。
更多细节可在Inside Windows NT High Resolution Timers中找到。
怎么做:
#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
的功能基本上通过使用bool值timeBeginPeriod
映射到函数timeEndPeriod
和 Set
(请参阅{ {3}}有关该计划及其所有影响的更多详细信息)。但是,多媒体套件将粒度限制为毫秒,NtSetTimerResolution
允许设置亚毫秒值。
答案 1 :(得分:0)
您可以使用MicroLibrary。看看:http://www.codeproject.com/Articles/98346/Microsecond-and-Millisecond-NET-Timer