Windows 服务 : Do work at specified times (Delphi)

标签 windows delphi winapi

只是检查在编写 Windows 服务时是否有任何最佳实践。

Service(单线程)需要定时工作,目前只能想到:

  1. 使用 sleep(),然后循环检查时间?
  2. 使用 TTimer?

有什么建议吗?

最佳答案

您的服务是单线程的并不重要,因为服务将始终在不同的线程上下文中调用其代码:

  • 服务管理器将启动、停止、暂停和恢复服务执行,并请求当前服务状态。

  • 服务本身将至少有一个线程执行真正的工作,它需要对来自服务管理器的请求使用react,根据请求更改服务执行状态,并返回请求的信息。服务需要在相当短的时间内响应来自服务管理器的请求,否则它会认为服务已挂起并杀死它。这就是为什么 - 如果服务可能有长时间执行或阻塞的代码 - 拥有多个服务线程可能会更好。

是否使用 Sleep() 或定时器消息也取决于服务线程中消息泵的可用性。如果您没有消息泵,您应该使用 Sleep() 或定时器回调。如果您有消息泵,因为您需要通过 Windows 消息与其他进程或线程通信,或者您需要执行 OLE 操作,那么使用计时器消息可能是最简单的方法。

几年前,我编写了一项用于定时后台执行任务的服务,类似于 Windows at 或 Unix cron 功能。它没有使用太多的 VCL,只使用了一些基类。服务的 Run() 方法如下所示:

procedure TScheduleService.Run;
var
  RunState: TServiceRunState;
begin
  while TRUE do begin
    RunState := GetServiceRunState;
    if (RunState = srsStopped) or (fEvent = nil) then
      break;
    if RunState = srsRunning then begin
      PeriodicWork;
      Sleep(500);
    end else
      fEvent.WaitFor(3000);
    Lock;
    if fServiceRunStateWanted <> srsNone then begin
      fServiceRunState := fServiceRunStateWanted;
      fServiceRunStateWanted := srsNone;
    end;
    Unlock;
  end;
end;

这在循环中使用了 Sleep(),但是解决方案使用了

while integer(GetMessage(Msg, HWND(0), 0, 0)) > 0 do begin
  TranslateMessage(Msg);
  DispatchMessage(Msg);
end;

也可以,然后可以使用 Windows 计时器消息。

关于Windows 服务 : Do work at specified times (Delphi),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1073351/

相关文章:

java - Windows : Delete directories

windows - 如何从批处理文件调用Powershell文件

delphi - Indy 是否在 XP 上使用某种协作式多任务处理,如果是,有没有办法切换到其他连接?

c - RegEnumValue 只返回 LOWORD

c - 在 list 中使用 requireAdministrator 恢复为 Windows 程序中的普通用户?

windows - 如何从另一个 tcl 文件调用一个 tcl 文件

sockets - Delphi:TCP打洞

Delphi: Hook TImageList 以按需加载图像

c++ - 使用 Win32 子类化现有窗口

c - 更新 WINAPI 中的文本框项目