Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>It doesn't really matter that your service is single-threaded, as a service will have its code always called in different thread contexts:</p> <ul> <li><p>The Service Manager will start, stop, pause and resume the service execution, and request the current service state.</p></li> <li><p>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.</p></li> </ul> <p>Whether to use <em>Sleep()</em> 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 <em>Sleep()</em> 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.</p> <p>A few years ago I wrote a service for timed background execution of tasks, similar to the Windows <code>at</code> or Unix <code>cron</code> functionality. It doesn't use much of the VCL, only some base classes. The <em>Run()</em> method of the service looks like this:</p> <pre><code>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 &lt;&gt; srsNone then begin fServiceRunState := fServiceRunStateWanted; fServiceRunStateWanted := srsNone; end; Unlock; end; end; </code></pre> <p>This uses <em>Sleep()</em> in a loop, but a solution using</p> <pre><code>while integer(GetMessage(Msg, HWND(0), 0, 0)) &gt; 0 do begin TranslateMessage(Msg); DispatchMessage(Msg); end; </code></pre> <p>would work just as well, and then Windows timer messages could be used.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload