I have a windows service written in C# that creates a truck load of threads and makes many network connections (WMI, SNMP, simple TCP, http). When attempting to stop the win
Matt Davis is pretty complete.
A few points;
If you have a thread that runs forever (because it has has a near-infinite loop and a catch all) and your service 's job is to run that thread, you probably want it to be a foreground thread.
Also, if any of your tasks are performing a longer operation such as a sproc call and so your Join timeout needs to be a little longer, you can actually asked the SCM for more time to shut down. See: https://msdn.microsoft.com/en-us/library/system.serviceprocess.servicebase.requestadditionaltime(v=vs.110).aspx This can be useful in avoiding the dreaded "marked for deletion" status. The maximum is set in the registry, so I usually request the max expected time the thread usually shuts down in (and never more than 12s). See: what is the maximum time windows service wait to process stop request and how to request for additional time
My code looks something like:
private Thread _worker;
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
protected override void OnStart(string[] args)
{
_worker = new Thread(() => ProcessBatch(_cts.Token));
_worker.Start();
}
protected override void OnStop()
{
RequestAdditionalTime(4000);
_cts.Cancel();
if(_worker != null && _worker.IsAlive)
if(!_worker.Join(3000))
_worker.Abort();
}
private void ProcessBatch(CancellationToken cancelToken)
{
while (true)
{
try
{
if(cancelToken.IsCancellationRequested)
return;
// Do work
if(cancelToken.IsCancellationRequested)
return;
// Do more work
if(cancelToken.IsCancellationRequested)
return;
// Do even more work
}
catch(Exception ex)
{
// Log it
}
}
}