In my Windows service, I create one “parent” foreground thread, which in turn spawns “child” threads using ThreadPool (which means they are the background) to complete the tasks.
What is the best way to close foreground threads gracefully at stopping windows service?
Here is my current implementation (devoid of logic for a specific task):
public partial class TaskScheduler : ServiceBase
{
private static AutoResetEvent _finishedTaskAutoResetEvent = new AutoResetEvent(false);
private bool StopRequested { get; set; }
private int _executingTasksCount;
private int ExecutingTasksCount { get { return _executingTasksCount; } }
private void IncCurrentTasksCount()
{
Interlocked.Increment(ref _executingTasksCount);
}
private void DecCurrentTasksCount()
{
Interlocked.Decrement(ref _executingTasksCount);
}
public TaskScheduler()
{
InitializeComponent();
Thread spawningThread = new Thread(DoSpawnTaskExecutionThreads);
spawningThread.Name = "Spawning Thread";
spawningThread.IsBackground = false;
spawningThread.Start();
}
protected override void OnStart(string[] args)
{
}
protected override void OnStop()
{
StopRequested = true;
}
private void DoSpawnTaskExecutionThreads()
{
while (!StopRequested)
{
while (!StopRequested && ExecutingTasksCount < MaxPooledTasks)
{
ThreadPool.QueueUserWorkItem(ExecuteTask, new Task());
IncCurrentTasksCount();
}
_finishedTaskAutoResetEvent.WaitOne();
}
while (ExecutingTasksCount > 0)
{
Thread.Sleep(200);
}
_eventLog.WriteEntry("The Spawning Thread finished along with task execution threads.");
}
private void ExecuteTask(object state)
{
try
{
Task task = (Task)state;
task.Execute();
}
catch
{
}
finally
{
DecCurrentTasksCount();
_finishedTaskAutoResetEvent.Set();
}
}
}
source
share