【发布时间】:2014-09-02 09:18:49
【问题描述】:
对于 Windows 服务,我需要一个计时器来定期执行某项任务。当然,有很多选项看起来优于定时器(多线程,直接从服务的主线程调用方法),但在这种特殊情况下它们都有其缺点。
但是,出于显而易见的原因,SetTimer() 不能在没有 GUI 的消息队列的情况下工作。我所做的(在 Free Pascal 中)如下:
创建计时器:
MyTimerID := SetTimer(0, 0, 3333, @MyTimerProc);
在服务的主循环中,运行定时器队列:
procedure TMyServiceThread.Execute;
var
AMessage: TMsg;
begin
repeat
// Some calls
if PeekMessage(AMessage, -1, WM_TIMER, WM_TIMER, PM_REMOVE) then begin
TranslateMessage(AMessage);
DispatchMessage(AMessage);
end;
// Some more calls
TerminateEventObject.WaitFor(1000);
until Terminated;
end;
最后,终止计时器:
KillTimer(0, MyTimerID)
除了 KillTimer 总是返回 False 之外,这按预期工作。
我对您的反馈很感兴趣,但是,如果我的实现是正确的 - 我只是想避免弄乱其他应用程序的消息和其他我不知道的副作用,因为我没有处理消息的经验。
谢谢!
【问题讨论】:
-
我会创建一个线程并等待取消事件指定的时间
-
@DavidHeffernan 我同意,出于一般考虑,我也更喜欢一个线程,但这在这里有它的缺点......只是想知道我的计时器实现是否很好:)
-
你没有展示你的实现。你没有显示循环。
-
@DavidHeffernan 已编辑,谢谢!
-
这是世界上最糟糕的事情。你有一个有点虚假的消息循环。你仍然有你等待的事件。你只是不需要计时器。删除所有这些并使用等待事件作为计时器。
标签: delphi winapi timer message-queue freepascal