2

Reading this question: Delphi Windows Service Design, I saw that most designer use this code below in the OnExecute of the TService or in the TThread method, in order to keep service alive.

while not Terminated do
begin
  // do something
end;

But what if I need (and I do) to create a service to respond (using Indy) to messages sent by the main application in order to send back some authentication data, what do I do with this code, ignore it or put some Sleep() in it?

Community
  • 1
  • 1
NaN
  • 8,596
  • 20
  • 79
  • 153
  • 2
    You don't need to implement the `OnExecute` event method of the `TService` class. It's optional. – TLama Jul 25 '13 at 17:47
  • 4
    TLama is right. It is best not to use the `OnExecute` event at all. You should move that logic to a separate worker thread that is started in the `OnStart` event and terminated in the `OnStop` event. If `OnExecute` is not assigned at all, `TService` will respond to SCM requests for you. But if `OnExecute` is assigned, you are responsible for calling `ServiceThread.ProcessRequests()` manually, and the service will stop itself when `OnExecute` exits. – Remy Lebeau Jul 25 '13 at 18:52

1 Answers1

7

Indy's TIdTCPServer and TIdUDPServer components are multi-threaded, so you don't really need to use the TService.OnExecute event at all. You could just activate them in the TService.OnStart event and deactivate them in the TService.OnStop event, and then assign handlers to the TIdTCPServer.OnExecute and TIdUDPServer.OnUDPRead events as needed. Both events are already looped for you, so you don't need a while not Terminated loop in them. Just read/process one request as needed, then exit, and wait for the next event to repeat. Let the server handle any exceptions that are raised. And keep in mind that TIdUDPServer has a ThreadedEvent property that is False by default, so you should set it to True inside a service.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Should I use the `AThread: TIdUDPListenerThread;` on the UDPRead to point to another function to be started instead of coding inside the UDPRead? What is the difference? – NaN Aug 05 '13 at 19:50
  • I do not understand what you are asking. The `AThread` parameter merely specifies which internal thread is receiving the data. It is primarily only useful for accessing the `TIdUDPListenerThread.Server` and `TIdUDPListenerThread.Data` properties. The `ABinding` parameter specifies the `TIdUDPServer.Binding` socket that received the data, so you can get Peer info from it, and send replies back on the same socket. Whether you decide to code your logic inside the `OnUDPRead` event handler directly or delegate to another function is up to you. – Remy Lebeau Aug 05 '13 at 22:17