Note that there are some explanatory texts on larger screens.

plurals
  1. POClose foreground thread gracefully on windows service stop
    primarykey
    data
    text
    <p>In my windows service I create one "parent" foreground thread that in turn spawns "child" threads using ThreadPool (which means they are background) to execute tasks.</p> <p>What is the best way to close foreground thread gracefully on windows service stop?</p> <p>Here is my current implementation (stripped out of task-specific logic):</p> <pre><code>public partial class TaskScheduler : ServiceBase { private static AutoResetEvent _finishedTaskAutoResetEvent = new AutoResetEvent(false); //This flag is used to increase chances of the Spawning Thread to finish gracefully when service stops. 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() { //We check StopRequested to try and finish this thread gracefully when service stops. while (!StopRequested) { while (!StopRequested &amp;&amp; ExecutingTasksCount &lt; MaxPooledTasks) { ThreadPool.QueueUserWorkItem(ExecuteTask, new Task()); IncCurrentTasksCount(); } _finishedTaskAutoResetEvent.WaitOne(); } //Either all task execution threads will finish or the process will be terminated forcibly. while (ExecutingTasksCount &gt; 0) { Thread.Sleep(200); //Check five times a second. } _eventLog.WriteEntry("The Spawning Thread finished along with task execution threads."); } private void ExecuteTask(object state) { try { Task task = (Task)state; task.Execute(); } catch { // Handle exception. } finally { DecCurrentTasksCount(); _finishedTaskAutoResetEvent.Set(); } } </code></pre> <p>}</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload