我遇到了一个与等待计时器的奇怪行为。如果我用一秒钟的时间创建它,那么在第一次射击之后,它的后续射击似乎“对齐”到某个毫秒值,这与第一次射击明显不同。
以下是开火时间的示例(小时:分钟:秒。毫秒):
18:06:25.753 <-- here 753
18:06:26.238 <-- here and later 238
18:06:27.238
18:06:28.238
18:06:29.238
如果我重新运行程序,第一次触发的毫秒值不同,但后续事件再次发生在238值。
以下是我使用的测试代码:
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hTimer = CreateWaitableTimer(NULL, FALSE, NULL);
LARGE_INTEGER dueTime;
dueTime.QuadPart = 0;
SetWaitableTimer(hTimer, &dueTime, 1000, NULL, NULL, FALSE);
for (int i=0; i<10; i++)
{
WaitForSingleObject(hTimer, INFINITE);
SYSTEMTIME st;
GetLocalTime(&st);
printf("%02d:%02d:%02d.%03d\n", st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
}
return 0;
}
我在Windows 7和Windows Server 2008 R2中看到此问题,但在Windows XP / Server 2003中没有。
任何人都知道为什么会这样?我可以想象,可以通过一些系统优化来减少定时器中断和/或上下文切换。但我无法在任何地方找到它。这是意料之外的,可能导致问题。
答案 0 :(得分:2)
dueTime.QuadPart = 0;
你对这个陈述有什么打算?
文档说:“正值表示绝对时间。”和“负值表示相对时间。”。零从不指定dueTime的可能值。
相反,您应通过指定
来找到合理的开始时间第一个事件发生的相对时间。
dueTime.QuadPart = -1000000;
// 100 ns units, first event at 100 ms from now
绝对时间
FILETIME FileTime;
LARGE_INTEGER dueTime;
GetSystemTimeAsFileTime(&FileTime);
CopyMemory(&dueTime,&FileTime,sizeof(FILETIME));
dueTime.QuadPart += 1000000;
// 100 ns units, first event at 100 ms from FileTime
注意:等待定时器允许以100 ns为单位指定到期时间。这并不意味着它们可以以这种准确度触发。准确性由系统时间粒度决定。有关系统时间粒度的更多详细信息,请参阅this answer。