Onestamente, dovrei dire che penso che tu sia un po 'fuori mano qui.
Prima di tutto, il codice effettivo pubblicato non ha molto senso; il thread di lavoro è in attesa di un segnale, ma senza motivo - non è in realtà in un ciclo di qualsiasi tipo o in attesa di una risorsa. In secondo luogo, se hai avuto bisogno di eseguire qualche (forse omesso) codice di ripulitura nel lavoratore dopo aver ricevuto il segnale di spegnimento, il tuo servizio potrebbe non dare al thread di lavoro abbastanza tempo per ripulire.
Ma, più fondamentalmente, tutto ciò che hai fatto è spostare il problema su un thread separato. Ciò può mantenere il servizio reattivo al controller di servizio ma non risolve il problema di progettazione e aggiunge un sacco di complessità non necessaria utilizzando i thread e i mutex; in ultima analisi, renderà il tuo servizio più difficile eseguire il debug se ne avrai la necessità.
Supponiamo che sia necessario eseguire qualche codice ogni 5 secondi. L'idea è, invece di "aspettare" 5 secondi, di invertire il controllo e lasciare che il timer invochi il tuo lavoro.
Questo è un male:
protected override void OnStart(string[] args)
{
while (true)
{
RunScheduledTasks(); // This is your "work"
Thread.Sleep(5000);
}
}
Questo è un bene:
public class MyService : ServiceBase
{
private Timer workTimer; // System.Threading.Timer
protected override void OnStart(string[] args)
{
workTimer = new Timer(new TimerCallback(DoWork), null, 5000, 5000);
base.OnStart(args);
}
protected override void OnStop()
{
workTimer.Dispose();
base.OnStop();
}
private void DoWork(object state)
{
RunScheduledTasks(); // Do some work
}
}
Questo è tutto. Questo è tutto quello che devi fare per lavorare a intervalli regolari. Finché il lavoro non viene eseguito per secondi alla volta, il servizio rimarrà sensibile al controller di servizio. Si può anche sostenere la pausa in questo scenario:
protected override void OnPause()
{
workTimer.Change(Timeout.Infinite, Timeout.Infinite);
base.OnPause();
}
protected override void OnContinue()
{
workTimer.Change(0, 5000);
base.OnContinue();
}
L'unico momento in cui è necessario per iniziare a creare i thread di lavoro nel servizio è quando l'opera stessa può funzionare per un tempo molto lungo ed è necessario la possibilità di cancellare in la metà. Questo tende a implicare una buona dose di impegno progettuale, quindi non entrerò in quello senza sapere con certezza che è legato al tuo scenario.
È meglio non iniziare a introdurre semantica multithread nel servizio a meno che non ne abbia davvero bisogno. Se stai solo provando a programmare piccole unità di lavoro da fare, sicuramente non ne hai bisogno.
Perché i nomi delle variabili sono in maiuscolo? –
Lì. Aggiustato. –