问题描述
对于Windows服务,我需要一个计时器来定期执行某些任务.当然,有许多选项似乎比计时器优越(多线程,直接从服务的主线程调用方法),但是在这种特定情况下,它们都有缺点.
For a Windows Service, I need a timer to perform a certain task regularly. Of course, there are many options that seem superior to a timer (multithreading, calling method directly from the service's main thread), but they all have their disadvantages in this particular situation.
但是,出于明显的原因,没有GUI的消息队列,SetTimer()无法工作.我所做的(在Free Pascal中)如下:
However, for obvious reasons, SetTimer() does not work without the message queue of a GUI. What I have done (in Free Pascal) is the following:
创建计时器:
MyTimerID := SetTimer(0, 0, 3333, @MyTimerProc);
在服务的主循环中,运行计时器队列:
In the main loop of the service, run the timer queue:
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之外,这可以按预期进行.
Except of KillTimer always returning False, this works as anticipated.
但是,如果您的实现正确,我会对您的反馈意见感兴趣-我只是想避免与其他应用程序的消息和其他我不知道的副作用混为一谈.
I am interested in your feedback, however, if my implementation is correct - I just want to avoid messing with other application's messages and other side effects I am not aware of because of my inexperience with message handling.
谢谢!
推荐答案
如注释中所述,您可能根本不需要计时器.您可以简单地使用事件等待时间来创建常规脉冲:
As discussed in the comments, you may not need a timer at all. You can simply use the timeout of the wait on your event to create a regular pulse:
while not Terminated do
begin
case TerminateEventObject.WaitFor(Interval) of
wrSignaled:
break;
wrTimeout:
// your periodic work goes here
wrError:
RaiseLastOSError;
end;
end;
脉冲周期将是间隔加上完成工作所需的时间.如果您需要一个特定的时间间隔,并且工作需要花费大量时间,那么雷米(Remy)建议使用可等待的计时器是值得的.
The period of the pulse will be the interval plus the time taken to do the work. If you need a specific interval, and the work takes significant time, the Remy's suggestion of a waitable timer is the thing to do.
不惜一切代价,您真正不想做的是使用基于消息循环的计时器.这不适用于服务.
What you really don't want to do, at all costs, is use a message loop based timer. That's not appropriate for a service.
这篇关于Windows Service中的计时器队列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!