title: System.Threading.Timer's Dispose method does not work with ManualResetEventSlim?
body: <p>I have the following code for a sample console app to simulate a Windows Service.</p>
  
  <pre><code>class Program
  {
      private Timer timer;
      private object syncRoot = new object();
      private bool stopSignalled = false;
      private ManualResetEventSlim mre = new ManualResetEventSlim(false);
      static void Main(string[] args)
      {
          Program p = new Program();
          p.Start();
          Console.ReadLine();
          p.Stop();
          Console.WriteLine("Stopped at:{0:G}", DateTime.Now);
      }
  
      private void Stop()
      {
          stopSignalled = true;
          mre.Wait();            
  
      }
      private void Timercallback(object state)
      {
          lock (syncRoot)
          {
              if (!stopSignalled)
              {
                   Console.WriteLine("Callback invoked  at:{0:G}",DateTime.Now);
  
              }
              else
              {
                  timer.Dispose(mre.WaitHandle);
                  Console.WriteLine("Timer disposed at:{0:G}", DateTime.Now);
              }
          }
  
      }
  
      private void Start()
      {
          Console.WriteLine("Started at:{0:G}",DateTime.Now);
          timer = new Timer(Timercallback,null,TimeSpan.Zero,TimeSpan.FromSeconds(1));
  
      }
  }
  </code></pre>
  
  <p>I was surprised that the Dispose overload which accepts a WaitHandle never signals the handle when using ManualResetEventSlim.
  If I change the code to use a ManualResetEvent instead like so, the handle is indeed signalled.</p>
  
  <pre><code>    class Program
  {
      private Timer timer;
      private object syncRoot = new object();
      private bool stopSignalled = false;
      private ManualResetEvent mre = new ManualResetEvent(false);
      static void Main(string[] args)
      {
          Program p = new Program();
          p.Start();
          Console.ReadLine();
          p.Stop();
          Console.WriteLine("Stopped at:{0:G}", DateTime.Now);
      }
  
      private void Stop()
      {
          stopSignalled = true;
          mre.WaitOne();            
  
      }
      private void Timercallback(object state)
      {
          lock (syncRoot)
          {
              if (!stopSignalled)
              {
                   Console.WriteLine("Callback invoked  at:{0:G}",DateTime.Now);
  
              }
              else
              {
                  timer.Dispose(mre);
                  Console.WriteLine("Timer disposed at:{0:G}", DateTime.Now);
              }
          }
  
      }
  
      private void Start()
      {
          Console.WriteLine("Started at:{0:G}",DateTime.Now);
          timer = new Timer(Timercallback,null,TimeSpan.Zero,TimeSpan.FromSeconds(1));
  
      }
  }
  </code></pre>
  
  <p>What gives!</p>