Service-Threads

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Service-Anwendungen

Jeder Service hat seinen eigenen Thread (Vcl.SvcMgr.TServiceThread). Falls Ihre Service-Anwendung also mehrere Services implementiert, achten Sie darauf, dass die Implementierung Ihrer Services thread-sicher ist. TServiceThread ist so angelegt, dass Sie den Dienst in der Ereignisbehandlungsroutine TService OnExecute implementieren können. Der Service-Thread hat seine eigene Execute-Methode, die eine Schleife enthält, welche die Ereignisbehandlungsroutinen OnStart und OnExecute des Service ausführt, bevor sie neue Anforderungen verarbeitet.

Weil die Verarbeitung von Service-Anforderungen lange dauern und die Service-Anwendung gleichzeitig Anforderungen von mehreren Clients entgegennehmen kann, ist es effizienter, für jede Anforderung einen neuen Thread aufzuspannen (abgeleitet von System.Classes.TThread, nicht von TServiceThread) und die Implementierung dieses neuen Service in die Execute-Methode des neuen Threads zu verschieben. Auf diese Weise kann die Execute-Schleife des Service-Threads fortlaufend neue Anforderungen verarbeiten, ohne auf das Ende der Ereignisbehandlungsroutine OnExecute warten zu müssen. Betrachten Sie dazu das folgende Beispiel.

Anmerkung:  Dieser Service erzeugt innerhalb des Service-Threads alle 500 Millisekunden einen Ton. Er ist zuständig für Pausen, Fortsetzung und Beenden des Threads, wenn der Service dazu aufgefordert wird.

So erstellen Sie das Beispiel:

  1. Wählen Sie Datei > Neu > Weitere und doppelklicken Sie im Dialogfeld Objektgalerie auf den Eintrag Service-Anwendung. Ein Fenster mit dem Namen Service1 wird angezeigt.
  2. Im interface-Abschnitt Ihrer Unit deklarieren Sie eine neue Ableitung von TThread namens TSparkyThread. Dieser Thread erledigt die Arbeit für Ihren Service. Die Deklaration sollte wie folgt aussehen:
 
 TSparkyThread = class(TThread)
   public
     procedure Execute; override;
 end;
 class TSparkyThread : public TThread
 {
 private:
 protected:
   void __fastcall Execute();
 public:
 __fastcall TSparkyThread(bool CreateSuspended);
 };
  1. Im Implementierungsabschnitt Ihrer Unit erzeugen Sie eine globale Variable für eine Instanz von TSparkyThread:
 
 var
   SparkyThread: TSparkyThread;
 TSparkyThread *SparkyThread;<!--Add the following code to the .cpp file for the TSparkyThread constructor:
 (I need a home!) -->// Diesen Quelltext dem Konstruktor hinzufügen
 __fastcall TSparkyThread::TSparkyThread(bool CreateSuspended)
 : TThread(CreateSuspended)
 {
 }
  1. Fügen Sie dem Implementierungsabschnitt der Methode Execute von TSparkyThread den folgenden Code hinzu:
 
 procedure TSparkyThread.Execute;
 begin
   while not Terminated do
   begin
     Beep;
     Sleep(500);
   end;
 end;
 void __fastcall TSparkyThread::Execute()
 {
   while (!Terminated)
   {
     Beep();
     Sleep(500);
   }
 }
  1. Markieren Sie das Service-Fenster (Service1) und doppelklicken Sie im Objektinspektor auf das Ereignis OnStart. Fügen Sie die folgende OnStart-Ereignisbehandlungsroutine ein:
 
 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;
 }
  1. Doppelklicken Sie im Objektinspektor auf das Ereignis OnContinue. Fügen Sie die folgende OnContinue-Ereignisbehandlungsroutine ein:
 
 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;
 }
  1. Doppelklicken Sie im Objektinspektor auf das Ereignis OnPause. Fügen Sie die folgende OnPause-Ereignisbehandlungsroutine ein:
 
 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;
 }
  1. Doppelklicken Sie schließlich im Objektinspektor auf das Ereignis OnStop und fügen Sie die folgende OnStop-Ereignisbehandlungsroutine ein:
 
 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;
 }


Bei der Entwicklung von Service-Anwendungen ist das Aufspannen neuer Threads von mehreren Faktoren abhängig, beispielsweise von der Art des bereitgestellten Service, der voraussichtlichen Anzahl der Verbindungen sowie der erwarteten Anzahl von Prozessoren auf dem Computer, der den Service ausführt.

Siehe auch