title: Techniques for exiting / cancelling while loops across threads: bool, ManualResetEvent or CancellationToken
body: <p>I am writing a program that has a few threads, each with a while loop that runs until the user specifies it should stop. I thought of a few ways to exit out of the loops, and subsequently the threads, and have outlined these approaches below.</p>
  
  <p><strong>Questions</strong></p>
  
  <ol>
  <li>Are there any pros and cons for each?</li>
  <li>Are there cases when you would use one and not another?</li>
  <li>I have a heard a few people say they prefer CancellationTokens for exiting threads. What is so appealing with that approach over the other two?</li>
  </ol>
  
  <p>Below follows the approaches.</p>
  
  <p><strong>The <code>bool</code> Approach</strong> </p>
  
  <p>Initially, I had declared a bool and just stated that the loops run until the the user sets the bool to false: <code>while(running) { Thread.Sleep(10); /*do work*/ }</code>. I then pondered if that is entirely thread-safe. What if the compiler did some optimization and moved the bool to a register. In that case, the threads would see different values for the bool. As a result, I marked the bool with the <code>volatile</code> keyword to avoid compiler optimizations.</p>
  
  <p><strong>The <code>ManualResetEvent</code> Approach</strong></p>
  
  <p>My next approach was to create a <code>ManualResetEvent</code>, and just say that the bool runs while WaitOne() is false: <code>while(!mre.WaitOne(10)) {/*do work*/}</code>. This will block for 10ms, then run the loop, over and over until we do <code>mre.Set()</code> and the loop exits.</p>
  
  <p><strong>The <code>CancellationToken</code> Approach</strong></p>
  
  <p>This approach I have not actually tried yet, but I read several places that people prefer cancelling threads this way. It is apparently thread-safe. One would define a <code>CancellationTokenSource</code>, call it <code>cts</code>, then pass <code>cts.Token</code> to the method run by the new thread and use an if statement to check if cancel has been requested: <code>while(!token.IsCancellationRequested) { Thread.Sleep(10); /*do work*/ }</code></p>
  
  <p><strong>UPDATE 1:</strong></p>
  
  <p>I found a similar post that concludes that the <code>MRE</code> approach is significantly slower than the <code>CancellationToken</code> approach. For full info, see here: <a href="https://stackoverflow.com/questions/13476528/stopping-a-thread-manualresetevent-volatile-boolean-or-cancellationtoken">Stopping a Thread, ManualResetEvent, volatile boolean or cancellationToken</a></p>
  
  <p><strong>UPDATE 2:</strong></p>
  
  <p>When it comes to comparing the <code>bool</code> approach to the other two, Eric Lippert has a good answer here: <a href="https://stackoverflow.com/questions/11953234/autoresetevent-vs-boolean-to-stop-a-thread">AutoResetEvent vs. boolean to stop a thread</a></p>
  
  <p><strong>UPDATE 3:</strong></p>
  
  <p>I found another relevant piece of information. CancellationTokens cannot be reset once cancelled. So it is not ideal for when you just want to cancel out of a loop temporarily, to start it again later. For that, MRE might be better (as you can Set and Reset, to your heart's content).</p>