title: Gracefully shutdown a thread
body: <p>In an application I'm developing, I have a main form that simply sits there and displays log data, and a worker thread that autonomously does the work in a loop.</p>
  
  <pre><code>MyWorker worker = new MyWorker();
  MainForm mainForm = new MainForm();
  
  // Subscribe form to log event so log data gets displayed
  worker.Log += mainForm.Log;
  
  // Start the worker thread's MainLoop
  new Thread(new ThreadStart(worker.MainLoop)).Start();
  
  // Show the form (blocking)
  Application.Run(mainForm);
  
  // If we end up here, the form has been closed and the worker has to stop running            
  worker.Running = false;
  </code></pre>
  
  <p>As you can see, whenever the form is closed, the worker thread should be stopped. The worker looks like this:</p>
  
  <pre><code>public class MyWorker
  {
      public String Running { get; set; }
  
      public MyWorker()
      {
          Running = true;
      }
  
      public void MainLoop()
      {
  
          while (Running)
          {
  
              DoExtensiveWork1();
              if (!Running) return;
  
              DoExtensiveWork2();
              if (!Running) return;
  
              DoExtensiveWork3();
              if (!Running) return;
  
              DoExtensiveWork4();
              if (!Running) return;
  
              DoExtensiveWork5();         
              if (!Running) return;
  
              // We have to wait fifteen minutes (900 seconds) 
              // before another "run" can be processed
              for (int i = 0; i &lt; 900; i++)
              {
                  Thread.Sleep(1000);
                  if (!Running) return;
              }
          }
      }
  }
  </code></pre>
  
  <p>As you can see, I want the thread to be able to stop when switching between successive work operations, but not when within an operation. When an operation (<code>DoExtensiveWorkN</code>) has finished, its status and results are persisted do disk or database, so quitting while an operation is in progress (by, for example, <code>Thread.Abort</code>) is not an option.</p>
  
  <p>However, I find this code I've just written repulsive to look at, especially the "wait loop" which sleeps for one second 900 times, to prevent the thread from idling for 15 minutes before detecting <code>Running</code> has been set to <code>false</code>.</p>
  
  <p>I'd rather be able to throw some kind of event to stop the main loop as soon as it's finished a piece of work.</p>
  
  <p>Can anyone point me in the right direction how to do this, or if a total rewrite is required because I totally misunderstood threading, show me somewhere where those principles are explained?</p>