title: Is it safe to use a boolean flag to stop a thread from running in C#
body: <p>My main concern is with the boolean flag... is it safe to use it without any synchronization? I've read in several places that it's atomic (including the documentation).</p>
  
  <pre><code>class MyTask
  {
      private ManualResetEvent startSignal;
      private CountDownLatch latch;
      private bool running;
  
      MyTask(CountDownLatch latch)
      {
          running = false;
          this.latch = latch;
          startSignal = new ManualResetEvent(false);
      }
  
      // A method which runs in a thread
      public void Run()
      {
          startSignal.WaitOne();
          while(running)
          {
              startSignal.WaitOne();
              //... some code
          }
          latch.Signal();
      }
  
      public void Stop()
      {
          running = false;
          startSignal.Set();
      }
  
      public void Start()
      {
          running = true;
          startSignal.Set();
      }
  
      public void Pause()
      {
          startSignal.Reset();
      }
  
      public void Resume()
      {
          startSignal.Set();
      }
  }
  </code></pre>
  
  <p>Is this a safe way to design a task in this way? Any suggestions, improvements, comments?</p>
  
  <p>Note: I wrote my custom <code>CountDownLatch</code> class in case you're wondering where I'm getting it from.</p>
  
  <p><strong>Update:</strong><br>
  Here is my CountDownLatch too: </p>
  
  <pre><code>public class CountDownLatch 
  {
      private volatile int m_remain;
      private EventWaitHandle m_event;
  
      public CountDownLatch (int count)
      {
          if (count &lt; 0)
              throw new ArgumentOutOfRangeException();
          m_remain = count;
          m_event = new ManualResetEvent(false);
          if (m_remain == 0)
          {
              m_event.Set();
          }
      }
  
      public void Signal()
      {
          // The last thread to signal also sets the event.
          if (Interlocked.Decrement(ref m_remain) == 0)
              m_event.Set();
      }
  
      public void Wait()
      {
          m_event.WaitOne();
      }
  }
  </code></pre>