为了实现我的Windows服务,我需要能够在系统处于工作状态的特定持续时间内设置计时器。所以我最初想出了以下代码。
A)设置一个等待计时器(省略错误检查):
HANDLE hWTimer = ::CreateWaitableTimer(NULL, FALSE, NULL);
//As an example, set timer to wait for 40 minutes
int nWaitMins = 40;
LARGE_INTEGER li;
ULONGLONG uiWaitMs = (ULONGLONG)nWaitMins * 60LL * 1000LL;
li.QuadPart = -10000LL * uiWaitMs; //Convert to 100 nanosecond intervals (must be negative for relative time)
::SetWaitableTimer(hWTimer, &li, 0, NULL, NULL, FALSE); //Don't wake the system
B)等待它(来自工人线程):
//Wait for timer to fire
::WaitForSingleObject(hWTimer, INFINITE);
这一点非常适用于一个警告(如果系统没有进入睡眠模式或休眠状态。)在这种情况下,最好地说明了这个图:
当我需要它做的时候是这样的:
我有什么计时器可以做我想要的吗?
PS。我的服务副本从多个工作站向我们的Web服务器提交报告。通过上面的技术,我尝试随机化提交时间以减轻服务器工作量。由于所有工作站都处于睡眠状态,然后大致同时被唤醒,当机器从睡眠状态唤醒时,我的“随机化”技术不起作用。
PS2。我需要指出,我需要在Windows XP下工作。
答案 0 :(得分:2)
当系统进入睡眠模式时,您需要收到通知,从此处开始。
当您收到WM_POWERBROADCAST
PBT_ABTSUSPEND
时,请停止计时器并跟踪剩余时间。收到PBT_ABTRESUMESUSPEND
事件后,请以剩余时间再次启动计时器。
答案 1 :(得分:0)
如果您只是希望所有工作站每40分钟发送一次报告(我可能在这里错了),您就不需要一个难以编程和调试的Windows服务。一个简单的计划任务就可以了。
为避免所有工作站同时发送报告,您只需在报告程序中设置随机等待期,在发送报告之前随机等待0-20分钟。因此,即使您按照相同的时间表安排每个工作站上的所有工作,报告也不会一起发送。
计划任务还可以唤醒您的工作站以发送报告。
答案 2 :(得分:0)
更新
如果您想根据挂钟时间(实际实时独立于系统睡眠/休眠)等待,您希望使用Win32线程池功能,例如CreateThreadPoolTimer或CreateThreadpoolWait。
如果你想根据系统时间(计算机实际上是醒着而不是睡觉的时间)等待,那么任何Win32 wait functions都可能就足够了。其中包括WaitForSingleObject和Sleep。
另外,对于它的价值,Win32中的C ++ condition_variable有一个名为wait_until的方法,但它实际上是用系统时间实现的。
最后,许多API都有可能出现虚假的唤醒现象。或者太早起床。由您的代码决定是否满足条件。如果您需要精确,最好的办法是在计时器回调完成之前和之后跟踪时间。然后衡量差异。对于系统时间,请使用GetTickCount64或GetTickCount。对于挂钟时间,请使用(具有讽刺意味)名为GetSystemTime的API。如果您发现您过早醒来,只需安排定时器再等待所需的时间长度。