Just checking if there's any best practice when writing a Windows Service.
The Service (Single-thread) needs to work at specified time intervals, right now I can only think of:
Any advice?
It doesn't really matter that your service is single-threaded, as a service will have its code always called in different thread contexts:
The Service Manager will start, stop, pause and resume the service execution, and request the current service state.
The service itself will have at least one thread doing the real work, which needs to react on the requests from the service manager, change the service execution state as requested, and return the requested information. A service needs to react to requests from the Service Manager in a reasonably short time, otherwise it will consider the service to be hung and kill it. That's why - if the service may have long-executing or blocking code - it may be better to have more than one service thread.
Whether to use Sleep() or timer messages does also depend on the availability of a message pump in the service threads. If you don't have a message pump you should use Sleep() or timer callbacks. If you have a message pump anyway, because you need to communicate with other processes or threads via Windows messages, or you need to do OLE stuff, then it may be easiest to use timer messages.
A few years ago I wrote a service for timed background execution of tasks, similar to the Windows at
or Unix cron
functionality. It doesn't use much of the VCL, only some base classes. The Run() method of the service looks like this:
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;
This uses Sleep() in a loop, but a solution using
while integer(GetMessage(Msg, HWND(0), 0, 0)) > 0 do begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
would work just as well, and then Windows timer messages could be used.
Does this need to be a service? Could you maybe setup a scheduled task in Windows?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With