On this step we'll add a code to the OnExecute event handler.
Note that this event handler is not necessary so if you do not need
to add a code to it then do not leave the empty OnExecute handler in
your code - it will break normal operation of the service.
There is only one rule that must be followed: the ProcessRequests
method should be called from this event handler. This method is an analog
of the Application.ProcessMessages in the regular application. The ProcessRequests
method has only one boolean parameter. The False value of this parameter
means that ProcessRequests should check the message queue for control
messages, process it if necessary and return. The True value means that
this method should not return until service terminates. So if you need
to do something while service runs use the OnExecute event as shown
below:
|
procedure TSampleService2.SampleService2Execute(Sender: TObject);
begin
while not Terminated do
begin
ProcessRequests(False);
DoWhatYouNeed;
end;
end;
|
The Terminated property indicates whether the service
should be stopped or it can continue working. In this example our "necessary
operation" will be sleeping again. Modify our example as shown below.
|
procedure TSampleService2.SampleService2Execute(Sender: TObject);
begin
while not Terminated do
begin
ProcessRequests(False);
Sleep(1000);
end;
end;
|
Please note that Terminated property is
changed as a result of ProcessRequests call. It means that OnStop event
can be fired during this call. If you free some memory in the OnStop
handler or destroy some objects that are used in the OnExecute main
loop then it is possible to get AV error. There is more safe way to
implement OnExecute loop:
|
procedure TSampleService2.SampleService2Execute(Sender: TObject);
begin
while True Terminated do
begin
ProcessRequests(False);
if Terminated then break;
DoWhatYouNeed;
end;
end;
|
Warning: The final part of this
step shows the problems that occur if the ProcessRequests call is lost.
It is recommended to use a debug mode to perform this test. In other
case you will have to restart your computer to stop uncontrollable service.
In addition it is recommended to change the service start mode (StartType
property) to stManual and reinstall service. It will prevent the automatic
service start after reboot.
Well, if you are ready to continue then save
changes, compile your example and run it. It works and can be controlled
as usually. Now try to comment the ProcessRequests call and test our
service again (in debug mode or not as you wish). You will see that
service starts normally but becomes uncontrollable after that. It does
not stop or pause because control requests are not processed. If you've
started the service in debug mode just close the debug window to terminate
it. In other case you will have to restart your computer.
The final conclusion is: call ProcessRequests(False)
periodically from the OnExecute event handler.
The next step of this example shows how to
use advanced tracing API to simplify the debugging of your application.