Ho un servizio Windows multithread in .Net 3.5 e sto avendo qualche problema a interrompere correttamente il servizio quando viene creato più di un thread.Arresto di un servizio Windows multithreading
Questo servizio utilizzato per creare solo un thread per fare tutto il lavoro, e ho appena cambiato per essere multi-threaded. Funziona perfettamente, ma quando il servizio viene interrotto, se viene eseguito più di un thread, questo verrà sospeso fino al completamento di tutti i thread.
All'avvio del servizio, ho creare un thread in background per gestire il processo principale:
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;
}
Ecco il metodo StartThreadPool:
//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;
}
ho creato una variabile statica in una classe separata per notificare ai thread che il servizio è stato interrotto. Quando il valore di questa variabile è vero, tutte le filettature devono arrestare il ciclo principale (una per ogni ciclo):
public static bool StopService;
Infine, il metodo OnStop:
protected override void OnStop()
{
DeliveryConstant.StopService = true;
//flag to tell the worker process to stop
serviceStarted = false;
workerThread.Join(TimeSpan.FromSeconds(30));
}
Nel metodo ProcessRequestList, al Alla fine di ogni foreach, controllo il valore della variabile StopService. Se è vero, interrompo il ciclo.
Ecco il problema: I thread sono creati in blocchi di 50 elementi. Quando ho 50 elementi o meno nel database, viene creato solo un thread e tutto funziona perfettamente. Quando ho più di 50 articoli, verranno creati più thread e quando provo a interrompere il servizio, non si fermerà finché tutti i thread in background non saranno completati.
Dai log, posso vedere che il metodo OnStop viene eseguito solo DOPO che tutti i thread sono stati completati.
Qualsiasi indizio su cosa potrebbe essere modificato per risolvere il problema?
Provare a mettere uno Sleep (50) nel ciclo while. –
Mi sembra che tu non abbia incluso la parte più importante del codice. Questa è l'implementazione del metodo ProcessRequestList. –
Puoi mostrare il codice in cui viene interrogato StopService? Cerca di usare CancellationToken su var statico, dato che è fatto per quel genere di cose. – hatchet