win32服务中的计时器

时间:2008-10-22 00:17:35

标签: c++ windows winapi windows-services

有人可以指出我在Win32服务中使用计时器的最简单方法吗?

我想我可以为此目的创建一个虚拟窗口,或者让第二个线程做滴答计数,但最好的是什么?有更优雅的方式吗?

提前致谢。

6 个答案:

答案 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).aspxhttp://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管理。您可以使用该系统为应用程序中的工作线程添加事件或互斥锁。