title: Console.ReadKey vs Console.ReadLine with a Timer
body: <p>The following code is a well known example to show the difference between a debug and release build:</p>
  
  <pre><code>using System;
  using System.Threading;
  
  public static class Program
  {
      public static void Main()
      {
          Timer t = new Timer(TimerCallback, null, 0, 2000);
          Console.ReadLine();
      }
  
      private static void TimerCallback(Object o)
      {
          Console.WriteLine("In TimerCallback: " + DateTime.Now);
          GC.Collect();
      }
  }
  </code></pre>
  
  <p>If you run this with a debug configuration, the timer will output the current time every two seconds. The <code>GC.Collect</code> doesn't have any effect because the compiler artificially extends the life of the <code>Timer t</code> variable. In a release configuration, the timer will execute only once. The <code>GC.Collect</code> will garbage collect the <code>t</code> variable and that's it.</p>
  
  <p>This all works like it should. The strange thing is, when you change the line Console.ReadLine to Console.ReadKey <em>both</em> configurations run the timer every two seconds.</p>
  
  <p>What is the difference between Console.ReadKey and Console.ReadLine? I understood <a href="http://msdn.microsoft.com/en-us/library/471w8d85.aspx" rel="noreferrer">from the documentation</a> that Console.ReadKey blocks the thread issuing the ReadKey method. But the GC.Collect still fires.. </p>
  
  <p><strong>Why is the lifetime of <code>Timer t</code> extended by blocking the main thread?</strong></p>
  
  <h2>Update</h2>
  
  <p>When using .NET 3.5, this behavior won't occur!</p>