Ich habe einen Multi-Thread-Windows-Dienst in .NET 3.5, und ich habe einige Probleme, den Dienst ordnungsgemäß zu stoppen, wenn mehr als ein Thread erstellt wird.Stoppen eines Multi-Thread-Windows-Dienstes
Dieser Dienst verwendet, um nur einen Thread zu erstellen, um die ganze Arbeit zu erledigen, und ich änderte es einfach zu Multithreading. Es funktioniert perfekt, aber wenn der Dienst beendet wird, wenn mehr als ein Thread ausgeführt wird, hängt es den Dienst, bis alle Threads abgeschlossen sind.
Wenn der Dienst gestartet wird, schaffe ich einen Hintergrund-Thread den Hauptprozess zu handhaben:
protected override void OnStart(string[] args)
{
try
{
//Global variable that is checked by threads to learn if service was stopped
DeliveryConstant.StopService = false;
bool SetMaxThreadsResult = ThreadPool.SetMaxThreads(10, 10);
ThreadStart st = new ThreadStart(StartThreadPool);
workerThread = new Thread(st);
workerThread.IsBackground = true;
serviceStarted = true;
workerThread.Start();
}
catch (Exception ex)
{
//Log something;
}
Hier ist die StartThreadPool Methode:
//Tried with and without this attribute with no success...
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
public void StartThreadPool()
{
while (serviceStarted)
{
ProcessInfo input = new ProcessInfo();
try
{
int? NumPendingRequests = GetItems(50, (Guid?)input.ProcessID);
if (NumPendingRequests > 0)
{
input.ProcessType = 1;
input.ProcessID = Guid.NewGuid();
ThreadPool.QueueUserWorkItem(new WaitCallback(new DispatchManager().ProcessRequestList), input);
}
}
catch (Exception ex)
{
//Some Logging here
}
}
DeliveryConstant.StopService = true;
}
I eine statische Variable in einer getrennten Klasse erstellt um die Threads zu benachrichtigen, dass der Dienst beendet wurde. Wenn der Wert für diese Variable wahr ist, sollten alle Fäden in die Hauptschleife stoppen (a für jede Schleife):
public static bool StopService;
schließlich die OnStop Methode:
protected override void OnStop()
{
DeliveryConstant.StopService = true;
//flag to tell the worker process to stop
serviceStarted = false;
workerThread.Join(TimeSpan.FromSeconds(30));
}
Im ProcessRequestList Verfahren, bei dem Am Ende jeder foreach überprüfe ich den Wert der StopService-Variable. Wenn das stimmt, breche ich die Schleife.
Hier ist das Problem: Die Threads werden in Blöcken von 50 Elementen erstellt. Wenn ich 50 Elemente oder weniger in der Datenbank habe, wird nur ein Thread erstellt, und alles funktioniert wunderbar. Wenn ich mehr als 50 Elemente habe, werden mehrere Threads erstellt, und wenn ich versuche, den Dienst zu stoppen, stoppt es nicht, bis alle Hintergrundthreads abgeschlossen sind.
Aus den Protokollen kann ich sehen, dass die Methode OnStop nur ausgeführt wird, nachdem alle Threads abgeschlossen sind.
Jeder Hinweis, was könnte geändert werden, um das zu beheben?
Versuchen Sie, einen Schlaf (50) in die While-Schleife zu setzen. –
Es scheint mir, dass Sie den wichtigsten Teil des Codes nicht enthalten haben. Das ist die Implementierung der ProcessRequestList-Methode. –
Können Sie Code anzeigen, in dem StopService abgefragt wird? Schauen Sie sich die Verwendung von CancellationToken über statische var an, wie es für diese Art von Sache gemacht wird. – hatchet