Each service has its own thread (TServiceThread), so if your service application implements more than one service you must ensure that the implementation of your services is thread-safe. TServiceThread is designed so that you can implement the service in the TServiceOnExecute event handler. The service thread has its own Execute method which contains a loop that calls the service's OnStart and OnExecute handlers before processing new requests.
Because service requests can take a long time to process and the service application can receive simultaneous requests from more than one client, it is more efficient to spawn a new thread (derived from TThread, not TServiceThread) for each request and move the implementation of that service to the new thread's Execute method. This allows the service thread's Execute loop to process new requests continually without having to wait for the service's OnExecute handler to finish. The following example demonstrates.
TSparkyThread = class(TThread) public procedure Execute; override; end;
class TSparkyThread : public TThread { private: protected: void __fastcall Execute(); public: __fastcall TSparkyThread(bool CreateSuspended); };
var
SparkyThread: TSparkyThread;
TSparkyThread *SparkyThread;// Add this code as the constructor __fastcall TSparkyThread::TSparkyThread(bool CreateSuspended) : TThread(CreateSuspended) { }
procedure TSparkyThread.Execute; begin while not Terminated do begin Beep; Sleep(500); end; end;
void __fastcall TSparkyThread::Execute() { while (!Terminated) { Beep(); Sleep(500); } }
procedure TService1.Service1Start(Sender: TService; var Started: Boolean); begin SparkyThread := TSparkyThread.Create(False); Started := True; end;
void __fastcall TService1::Service1Start(TService *Sender, bool &Started) { SparkyThread = new TSparkyThread(false); Started = true; }
procedure TService1.Service1Continue(Sender: TService; var Continued: Boolean); begin SparkyThread.Resume; Continued := True; end;
void __fastcall TService1::Service1Continue(TService *Sender, bool &Continued) { SparkyThread->Resume(); Continued = true; }
procedure TService1.Service1Pause(Sender: TService; var Paused: Boolean); begin SparkyThread.Suspend; Paused := True; end;
void __fastcall TService1::Service1Pause(TService *Sender, bool &Paused) { SparkyThread->Suspend(); Paused = true; }
procedure TService1.Service1Stop(Sender: TService; var Stopped: Boolean); begin SparkyThread.Terminate; Stopped := True; end;
void __fastcall TService1::Service1Stop(TService *Sender, bool &Stopped) { SparkyThread->Terminate(); Stopped = true; }
When developing server applications, choosing to spawn a new thread depends on the nature of the service being provided, the anticipated number of connections, and the expected number of processors on the computer running the service.
Copyright(C) 2009 Embarcadero Technologies, Inc. All Rights Reserved.
|
What do you think about this topic? Send feedback!
|