title: ManualResetEvent.WaitOne() doesn't return if Reset() is called immediately after Set()
body: <p>I have a problem in a production service which contains a "watchdog" timer used to check whether the main processing job has become frozen (this is related to a COM interop problem which unfortunately can't be reproduced in test).</p>
  
  <p>Here's how it currently works:</p>
  
  <ul>
  <li>During processing, the main thread resets a <a href="http://msdn.microsoft.com/en-us/library/vstudio/2ssskfws%28v=vs.90%29.aspx" rel="nofollow noreferrer"><code>ManualResetEvent</code></a>, processes a single item (this shouldn't take long), then sets the event. It then continues to process any remaining items.</li>
  <li>Every 5 minutes, the watchdog calls <code>WaitOne(TimeSpan.FromMinutes(5))</code> on this event. If the result is false, the service is restarted.</li>
  <li>Sometimes, during normal operation, the service is being restarted by this watchdog even though processing takes nowhere near 5 minutes.</li>
  </ul>
  
  <p>The cause appears to be that when multiple items await processing, the time between the <code>Set()</code> after the first item is processed, and the <code>Reset()</code> before the second item is processed is too brief, and <code>WaitOne()</code> doesn't appear to recognise that the event has been set.</p>
  
  <p>My understanding of <code>WaitOne()</code> is that the blocked thread is <a href="http://msdn.microsoft.com/en-us/library/58195swd.aspx" rel="nofollow noreferrer">guaranteed to receive a signal when <code>Set()</code> is called</a>, but I assume I'm missing something important.</p>
  
  <p>Note that if I allow a context switch by calling <code>Thread.Sleep(0)</code> after calling <code>Set()</code>, <code>WaitOne()</code> never fails. </p>
  
  <p>Included below is a sample which produces the same behaviour as my production code. <code>WaitOne()</code> sometimes waits for 5 seconds and fails, <em>even though <code>Set()</code> is being called every 800 milliseconds</em>.</p>
  
  <pre><code>private static ManualResetEvent _handle;
  
  private static void Main(string[] args)
  {
      _handle = new ManualResetEvent(true);
  
      ((Action) PeriodicWait).BeginInvoke(null, null);
      ((Action) PeriodicSignal).BeginInvoke(null, null);
  
      Console.ReadLine();
  }
  
  private static void PeriodicWait()
  {
      Stopwatch stopwatch = new Stopwatch();
  
      while (true)
      {
          stopwatch.Restart();
          bool result = _handle.WaitOne(5000, false);
          stopwatch.Stop();
          Console.WriteLine("After WaitOne: {0}. Waited for {1}ms", result ? "success" : "failure",
                              stopwatch.ElapsedMilliseconds);
          SpinWait.SpinUntil(() =&gt; false, 1000);
      }
  }
  
  private static void PeriodicSignal()
  {
      while (true)
      {
          _handle.Reset();
          Console.WriteLine("After Reset");
          SpinWait.SpinUntil(() =&gt; false, 800);
          _handle.Set();
          // Uncommenting either of the lines below prevents the problem
          //Console.WriteLine("After Set");
          //Thread.Sleep(0);
      }
  }
  </code></pre>
  
  <p><img src="https://i.stack.imgur.com/7G5KA.png" alt="output of the above code"></p>
  
  <hr>
  
  <p><strong>The Question</strong></p>
  
  <p>While I understand that calling <code>Set()</code> closely followed by <code>Reset()</code> doesn't guarantee that all blocked threads will resume, is it also not guaranteed that <em>any</em> waiting threads will be released?</p>