9

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

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

提前致谢。

4

6 回答 6

15

您可以使用计时器队列 ( http://msdn.microsoft.com/en-us/library/ms686796.aspx )。他们不需要 HWND。

于 2008-10-22T00:31:22.407 回答
5

除了使用 UI 计时器(即使您可以使用 1800-INFO 先生所示的 NULL 窗口句柄),您还可以使用内核可等待计时器对象。请参阅API 文档中的CreateWaitableTimer。然后可以使用 WaitForSingleObject 或 WaitForMultipleObjects 等来等待这些,如果这已经是您的服务等待外部事件的方式,这将特别有用。

如果从第一个链接中不清楚,SetWaitableTimer 函数可以将完成例程(用户回调)与计时器相关联。请记住使用...Ex 版本的 WaitForMultipleObjects (等),以便线程处于“可提醒”状态。

于 2008-10-22T00:34:54.087 回答
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...

Timer 回调将由 DispatchMessage 调用。这个问题让我想起了最近的ONT

于 2008-10-22T00:30:30.180 回答
1

您可以使用 SetTimer 设置计时器,然后在消息循环中捕获 WM_TIMER 消息。

例子:

// 设置一个10秒后过期的定时器

SetTimer(hwnd,IDT_TIMER1, 10000,(TIMERPROC) NULL);

...然后在消息循环中:

开关(wParam)

{ 

    case IDT_TIMER1: 

        // Boom goes the dynamite

如果您不想进行消息循环处理,您还可以取消 TIMERPROC 类型的函数并在计时器到期时调用该函数。

于 2008-10-22T00:24:53.233 回答
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了解您为什么应该这样做。

于 2008-10-23T12:30:55.777 回答
0

你只是想时不时地“醒来”做一些工作吗?您始终可以使用 Sleep()。

此外,我通常有一个线程在 while(1 == 1) 循环中,里面有一个睡眠。在那里我可以检查关闭请求和其他杂项家务。您可以使用该系统为应用程序中的工作线程触发事件或互斥锁。

于 2008-10-22T00:41:51.623 回答