title: Why does ManualResetEventSlim.Wait appear not to block for the full wait time?
body: <p>So I am using <code>System.Threading.ManualResetEventSlim</code> in my code and I happened to notice that sometimes when I call <code>Wait(TimeSpan)</code> the time spent waiting is significantly less than the time specified.</p>
  
  <p>Here is a unit test that demonstrates my situation</p>
  
  <pre><code>using System;
  using System.Diagnostics;
  using NUnit.Framework;
  
  namespace DB
  {
      [TestFixture]
      public class ManualResetEventSlimTests
      {
          [Test]
          [Repeat(100)]
          public void TestThatWait_ShouldBlockForAtLeastAsLongAsTheWaitTimeout_IfNotSignalled()
          {
              TimeSpan waitTime = TimeSpan.FromMilliseconds(250);
              using (var waiter = new System.Threading.ManualResetEventSlim(false))
              {
                  var stopwatch = System.Diagnostics.Stopwatch.StartNew();
                  waiter.Wait(waitTime);
                  Assert.That(stopwatch.Elapsed, Is.GreaterThanOrEqualTo(waitTime));
              }
          }
      }
  }
  </code></pre>
  
  <p>This test will pass most of the time but when repeated 100 times there is always at least 1 failure because the time measured by the stopwatch is less than the specified wait TimeSpan. A typical failure is </p>
  
  <p>Expected: greater than or equal to 00:00:00.2500000
     But was:  00:00:00.2497514</p>
  
  <p>My first thought was that the stopwatch was not accurate enough but that appears not to be the case; the <code>Stopwatch.Frequency</code> = 3507511, which means that it should be accurate to something like 285ns per tick i.e. much, much less than the discrepancy of 0.25ms (assuming that it can accurately count ticks).</p>
  
  <p>The fact that it waits a few fractions of a ms less than I expected does not have any impact on my particular program but I was curious and my Google-foo did not uncover anything relevant. So I put it to the SO community to see if someone has a reasonable explanation.</p>