问题描述
我需要编写一个程序 (.NET C#),它正在做一些事情,但每 0.5 毫秒我需要读取一些数据并查看它是否更改为某个值或高于该值,以及该值是否已达到该目标,停止我正在做的所有其他事情.将计时器设置为每 0.5 毫秒运行一次是否有问题?这种程序的正确方法是什么?
I need to write a program (.NET C#) which is doing some stuff but every 0.5 ms I need to read some data and see if it changed to a certain value or above it and if that value has reached that goal, stop everything else I'm doing.Is there a problem with setting a timer to run every 0.5 ms?What is the proper approach for this kind of programs?
推荐答案
1 ms 还是 0.5 ms?
Hans 是对的,多媒体定时器接口能够提供低至 1 毫秒的分辨率.请参阅关于多媒体计时器 (MSDN), 获取和设置计时器分辨率 (MSDN),以及此答案以了解有关timeBeginPeriod的更多详细信息代码>.注意:不要忘记调用 timeEndPeriod 完成后切换回默认的计时器分辨率.
1 ms or 0.5 ms?
Hans is right, the multimedia timer interface is able to provide down to 1 ms resolution.See About Multimedia Timers (MSDN), Obtaining and Setting Timer Resolution (MSDN), and this answer for more details about timeBeginPeriod
. Note: Don't forget to call the timeEndPeriod to switch back to the default timer resolution when done.
怎么做:
#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);
注意:此过程也可用于其他进程,并且获得的分辨率适用于系统范围.任何进程要求的最高分辨率都将处于活动状态,请注意后果.
Note: This procedure is available to other processes as well and the obtained resolution applies system wide. The highest resolution requested by any process will be active, mind the consequences.
但是,您可以通过隐藏的 API NtSetTimerResolution()
获得 0.5 毫秒 的分辨率.NtSetTimerResolution
由本地 Windows NT 库 NTDLL.DLL 导出.请参阅 如何将计时器分辨率设置为 0.5 毫秒? 在 MSDN 上.然而,真正可实现的分辨率是由底层硬件决定的.现代硬件确实支持 0.5 毫秒的分辨率.在Inside Windows NT High Resolution Timers中可以找到更多详细信息.
However, you may obtain 0.5 ms resolution by means of the hidden API NtSetTimerResolution()
.NtSetTimerResolution
is exported by the native Windows NT library NTDLL.DLL. See How to set timer resolution to 0.5ms ? on MSDN. Nevertheless, the true achievable resolution is determined by the underlying hardware. Modern hardware does support 0.5 ms resolution.Even more details are found in 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
的功能基本上被映射到函数 timeBeginPeriod
和 timeEndPeriod
使用 bool值 Set
(参见 Inside Windows NT High Resolution计时器 了解有关该计划及其所有影响的更多详细信息).但是,多媒体套件将粒度限制为毫秒,并且 NtSetTimerResolution
允许设置亚毫秒值.
Note: The functionality of NtSetTimerResolution
is basically mapped to the functions timeBeginPeriod
and timeEndPeriod
by using the bool value Set
(see Inside Windows NT High Resolution Timers for more details about the scheme and all its implications). However, the multimedia suite limits the granularity to milliseconds and NtSetTimerResolution
allows to set sub-millisecond values.
这篇关于定时器最小限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!