Delphi中Windows服务的计时器队列是如何实现的?
- 内容介绍
- 文章标签
- 相关推荐
本文共计521个文字,预计阅读时间需要3分钟。
对于Windows服务,我需要一个计时器来安排执行特定任务。虽然可能有多种选择,例如多线程或直接从服务的主线程调用,但这些方法在特定情况下都存在不足。然而,显然这些方法都有它们各自的局限性。
对于 Windows服务,我需要一个计时器来定期执行某项任务.当然,有许多选项似乎优于计时器(多线程,直接从服务的主线程调用方法),但它们在这种特殊情况下都有它们的缺点.但是,由于显而易见的原因,如果没有GUI的消息队列,SetTimer()将无法工作.我所做的(在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之外,这可以按预期工作.
我对你的反馈很感兴趣,但是,如果我的实现是正确的 – 我只是想避免弄乱其他应用程序的消息以及我不知道的其他副作用,因为我对消息处理经验不足.
谢谢!
正如评论中所讨论的,您可能根本不需要计时器.您可以简单地使用事件等待的超时来创建常规脉冲:while not Terminated do begin case TerminateEventObject.WaitFor(Interval) of wrSignaled: break; wrTimeout: // your periodic work goes here wrError: RaiseLastOSError; end; end;
脉冲的周期将是间隔加上完成工作所需的时间.如果您需要一个特定的间隔,并且工作需要很长时间,那么Remy建议使用等待计时器就可以了.
不惜一切代价,你真正不想做的是使用基于消息循环的计时器.这不适合服务.
本文共计521个文字,预计阅读时间需要3分钟。
对于Windows服务,我需要一个计时器来安排执行特定任务。虽然可能有多种选择,例如多线程或直接从服务的主线程调用,但这些方法在特定情况下都存在不足。然而,显然这些方法都有它们各自的局限性。
对于 Windows服务,我需要一个计时器来定期执行某项任务.当然,有许多选项似乎优于计时器(多线程,直接从服务的主线程调用方法),但它们在这种特殊情况下都有它们的缺点.但是,由于显而易见的原因,如果没有GUI的消息队列,SetTimer()将无法工作.我所做的(在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之外,这可以按预期工作.
我对你的反馈很感兴趣,但是,如果我的实现是正确的 – 我只是想避免弄乱其他应用程序的消息以及我不知道的其他副作用,因为我对消息处理经验不足.
谢谢!
正如评论中所讨论的,您可能根本不需要计时器.您可以简单地使用事件等待的超时来创建常规脉冲:while not Terminated do begin case TerminateEventObject.WaitFor(Interval) of wrSignaled: break; wrTimeout: // your periodic work goes here wrError: RaiseLastOSError; end; end;
脉冲的周期将是间隔加上完成工作所需的时间.如果您需要一个特定的间隔,并且工作需要很长时间,那么Remy建议使用等待计时器就可以了.
不惜一切代价,你真正不想做的是使用基于消息循环的计时器.这不适合服务.

