Windows Service – OnStart mal etwas anders !

Nachdem ich in einem Projekt mit dem Problem kämpfen musste, das einer der für dieses Projekt entwickelten Windows Dienste durch eine aufwendige Initialisierung bis zu einer Minute in der OnStart Methode verweilt hat bis er endlich den Dienst als gestartet anzeigt habe ich mir überlegt wie man diese Problem anders lösen könnte.

Eigentlich war das auch kein wirklich großes Problem, aber da ich auch erst einmal gezielt darüber Nachdenken musste um auf die Lösung zu kommen, denke ich dass vielleicht auch andere erst einmal auf das Problem aufmerksam werden müssen um dann einen anderen Ansatz zum Start der Windows Dienste zu verwenden.

Im Nachfolgenden Beschreibe ich eine einfach Lösung wie man einen Windows Dienst mit Hilfe eines Timers dazu bringt, sofort zu starten, unabhängig davon, ob aufwendige Initialisierungsprozesse für den Dienst durchgeführt werden müssen oder nicht.

Schauen wir und doch einfach mal wie der normale Startvorgang eines Dienstes aussieht:

Hier ein Beispiel wie es normalerweise aussehen kann, wobei osc irgendeine Klasse ist deren Methoden nach deren Initialisierung vom Service verwendet werden:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Diagnostics;

using System.ServiceProcess;

using System.Text;

using System.Timers; 
 


namespace Namespace.Service

{

      publicpartialclassMeinService : ServiceBase

      {

            MeineKlasse osc;

            public MeinService()

            {

                  InitializeComponent();

                  Osc = new Osc();

            } 


            protectedoverridevoid OnStart(string[] args)

            {

                  Osc.Init();

                  Osc.StartAll();

            } 


            protectedoverridevoid OnStop()

            {

                  osc.StopAll();

            } 


            protectedoverridevoid OnContinue()

            {

                  osc.StartAll();

            } 


            protectedoverridevoid OnPause()

            {

                  osc.StopAll();

            } 


            protectedoverridevoid OnShutdown()

            {

                  osc.StopAll();

                  osc.Dispose();

                  osc = null; 


            }

      } 

Wenn nun davon ausgehen dass Osc.Init() und Osc.StartAll() Methoden sind die lange dauern können, dann befindet sich dieser Dienst in der Gesamt Zeit in welcher diese beiden Methoden ausgeführt werden im Dienst- Status StartPending. Dies kann in bestimmten Situationen aber mehr als unerwünscht sein. Und für diesen Fall habe ich folgende Änderungen vorgenommen, die dazu führen, dass der Service sofort nach dem Start wirklich in den Status Running übergeht.

Nachfolgend nun die Lösung für das Problem:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Diagnostics;

using System.ServiceProcess;

using System.Text;

using System.Timers ; 
 


namespace Namespace.Service

{

      publicpartialclassMeinService : ServiceBase

      {

            Timer startTimer = newTimer();

            MeineKlasse osc;

            public MeinService()

            {

                  InitializeComponent();

                  startTimer.Interval = 1000;        // 1 seconds 

                  startTimer.Elapsed += newElapsedEventHandler(startTimer_Elapsed);

                  startTimer.Enabled = false;

            } 


            void startTimer_Elapsed(object sender, ElapsedEventArgs e)

            {

                  startTimer.Enabled = false;

                  osc = MeineKlasse.loadActiveSystems();

                  osc.StartAll();

            } 


            protectedoverridevoid OnStart(string[] args)

            {

                  startTimer.Enabled = true;

            } 


            protectedoverridevoid OnStop()

            {

                  osc.StopAll();

            } 


            protectedoverridevoid OnContinue()

            {

                  osc.StartAll();

            } 


            protectedoverridevoid OnPause()

            {

                  osc.StopAll();

            } 


            protectedoverridevoid OnShutdown()

            {

                  osc.StopAll();

                  osc.Dispose();

                  osc = null; 


            }

      }

} 

Ich habe die Änderungen in Fettschrift dargestellt damit man diese gleich auf Anhieb erkennen kann.
Und die Erklärung ist eigentlich auch selbstredend.
Ich verwende also einen Timer, der vom OnStart Event eine Sekunde nach dem der Service gestartet wurde die eigentlichen Funktionen des Service aktiviert.

Manchmal ist einfach, einfach Einfach !

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.