Wie kann ich einen Windows-Dienst mit mehreren Threads ordnungsgemäß beenden?

Ich habe einen in C # geschriebenen Windows-Dienst, der eine Lastwagenladung von Threads erstellt und viele Netzwerkverbindungen herstellt (WMI, SNMP, einfaches TCP, http). Wenn Sie versuchen, den Windows-Dienst mithilfe des Dienste-MSC-Snap-Ins zu beenden, wird der Aufruf zum Beenden des Diensts relativ schnell zurückgegeben, der Vorgang wird jedoch ca. 30 Sekunden lang ausgeführt.

Die Hauptfrage ist, was der Grund dafür sein könnte, dass das Anhalten mehr als 30 Sekunden dauert. Was kann ich suchen und wie suche ich danach?

Die zweite Frage ist, warum das Dienst-msc-Snap-In (Dienst-Controller) zurückkehrt, obwohl der Prozess noch ausgeführt wird. Gibt es eine Möglichkeit, die Rückgabe erst dann zu veranlassen, wenn der Prozess tatsächlich beendet wurde?

Hier ist der Code in der OnStop-Methode des Dienstes

protected override void OnStop()
{
   //doing some tracing
   //......

   //doing some minor single threaded cleanup here
   //......

   base.OnStop();

   //doing some tracing here
}

Als Antwort auf die Antworten zur Thread-Bereinigung bearbeiten

Viele von Ihnen haben geantwortet, dass ich alle meine Threads nachverfolgen und sie dann bereinigen soll. Ich halte das nicht für einen praktischen Ansatz. Erstens habe ich nicht Zugriff auf alle verwalteten Threads an einem Ort. Die Software ist ziemlich groß mit verschiedenen Komponenten, Projekten und sogar DLLs von Drittanbietern, die alle Threads erstellen könnten. Es gibt keine Möglichkeit, alle an einem Ort zu verfolgen oder ein Flag zu haben, das alle Threads prüfen (selbst wenn ich alle Threads ein Flag prüfen lassen könnte, blockieren viele Threads Dinge wie Semaphoren. Wenn sie blockieren, können sie es Ich muss sie mit einer Zeitüberschreitung warten lassen, dann diese globale Markierung und das Warten erneut prüfen.

Das IsBackround-Flag ist eine interessante Sache, die überprüft werden muss. Wie kann ich jedoch herausfinden, ob Forground-Threads in der Nähe laufen? Ich muss jeden Abschnitt des Codes überprüfen, der einen Thread erstellt. Gibt es einen anderen Weg, vielleicht ein Tool, mit dem ich das herausfinden kann?

Letztendlich hört der Prozess jedoch auf. Es scheint nur, dass ich auf etwas warten muss. Wenn ich jedoch in der OnStop-Methode auf die Zeitspanne X warte, dauert es ungefähr 30 Sekunden + X, bis der Vorgang beendet ist. Egal was ich versuche, es scheint, dass der Prozess ungefähr 30 Sekunden benötigt (es sind nicht immer 30 Sekunden, er kann variieren), nachdem der OnStop zurückgekehrt ist, damit der Prozess tatsächlich anhält.

Antworten auf die Frage(7)

Ihre Antwort auf die Frage