有人可以指出我在Win32服务中使用计时器的最简单方法吗?
我想我可以为此目的创建一个虚拟窗口,或者让第二个线程做滴答计数,但最好的是什么?有更优雅的方式吗?
提前致谢。
答案 0 :(得分:15)
您可以使用计时器队列(http://msdn.microsoft.com/en-us/library/ms686796.aspx)。它们不需要HWND。
答案 1 :(得分:5)
您可以使用内核等待计时器对象,而不是使用UI计时器(即使您可以使用1800-INFO先生所示的NULL窗口句柄)。请参阅API文档中的CreateWaitableTimer。然后可以使用WaitForSingleObject或WaitForMultipleObjects等等这些等待,如果您的服务已经等待外部事件,这将非常有用。
如果第一个链接不清楚,则SetWaitableTimer函数可以将完成例程(用户回调)与计时器相关联。请记住使用... WaitForMultipleObjects(等)的Ex版本,以便线程处于“可警告”状态。
答案 2 :(得分:4)
您可以发送主线程WM_TIMER消息。消息的lParam是回调函数的地址,或者您可以将其保留为NULL并在消息泵中自行处理它。
在这个例子中,我们将定时器发送到线程消息泵,不需要有一个与定时器相关联的窗口。
UINT timer;
VOID CALLBACK Timer(HWND hwnd,
UINT uMsg,
UINT_PTR idEvent,
DWORD dwTime
)
{
KillTimer(0, timer);
}
timer=SetTimer(0, // window handle
0, // id of the timer message, leave 0 in this case
10000, // millis
Timer // callback
);
// pump messages
while (GetMessage) etc...
DispatchMessage将调用Timer回调。这个问题让我想起了最近的ONT。
答案 3 :(得分:1)
您可以使用SetTimer设置计时器,然后在消息循环中捕获WM_TIMER消息。
示例:
//将计时器设置为10秒后过期
SetTimer(hwnd,IDT_TIMER1,10000,(TIMERPROC)NULL);
...然后在消息循环中:
开关(wParam)
{
case IDT_TIMER1:
// Boom goes the dynamite
如果你不想进行消息循环处理,你也可以取消TIMERPROC类型的函数并在计时器到期时调用它。
答案 4 :(得分:1)
在你的一条评论中,你说“......服务正在处理其他线程中的内容,我只需要每秒检查一些文件的状态。”
轮询不是检查文件状态的最佳方式,会对系统性能产生负面影响。虽然在网络上有(通常)问题这样做,但您应该查看http://msdn.microsoft.com/en-us/library/aa364417(VS.85).aspx或http://msdn.microsoft.com/en-us/library/aa365261(VS.85).aspx了解如何执行此操作,并http://blogs.msdn.com/oldnewthing/archive/2006/01/24/516808.aspx查看您应该这样做的原因。
答案 5 :(得分:0)
你是不是偶尔想要“醒来”做一些工作?你总是可以使用Sleep()。
此外,我通常有一个在一段时间内(1 == 1)循环的线程,里面有一个睡眠。在那里,我可以检查关机请求和其他misc管理。您可以使用该系统为应用程序中的工作线程添加事件或互斥锁。