title: Message pump in a console application
body: <p>I have a fairly simple console application written in .NET. Sometimes the application is run in batch mode without an operator, other times it is run "out of pocket". If it's running in batch mode, there is a defined default option which allows the program to run automatically. If there is an operator present, there are other options which allow the user to select from a list of functions.</p>
  
  <p>For reasons I don't want to go into, command-line parameters are not preferred. Instead, I've created a 10-second window in which an operator may choose a function. Currently, I'm using a simple while loop and reading input from the "in" stream. I've added a <a href="http://msdn.microsoft.com/en-us/library/system.threading.thread.sleep%28v=vs.110%29.aspx" rel="nofollow">Thread.Sleep</a> call at the end to prevent the while loop from completely consuming the processor, but I'd like to know if there's a better way.</p>
  
  <p>In a Windows application (<a href="http://en.wikipedia.org/wiki/Windows_Forms" rel="nofollow">Windows Forms</a> or <a href="http://en.wikipedia.org/wiki/Windows_Presentation_Foundation" rel="nofollow">WPF</a>) there is a message pump which is able to read the queue of messages and then return control to the system. Even heavy-duty applications like Visual Studio, <a href="http://en.wikipedia.org/wiki/SAS_%28software%29#Technical_overview_and_terminology" rel="nofollow">SAS Enterprise Guide</a> and <a href="http://en.wikipedia.org/wiki/SQL_Server_Management_Studio" rel="nofollow">SQL Server Management Studio</a> use practically 0% of the processor when they are idle. Can I get the same effect with my console application?</p>
  
  <p>The Thread.Sleep is working, but, as I said, I want to know if there's a better way.</p>
  
  <p>Here's the source code:</p>
  
  <pre><code>class Program {
      static void Main( string[] args ) {
  
          DateTime l_startTime = DateTime.Now;
  
          Console.CursorVisible = false;
          Console.WriteLine( "Please select an option within 10 seconds..." );
          Console.WriteLine( "" );
          Console.WriteLine( " [1] Option A (DEFAULT)" );
          Console.WriteLine( " [2] Option 2" );
          Console.WriteLine( " [3] Option III" );
  
          int l_elapsedSeconds = 0;
  
          bool l_exit = false;
          while ( !l_exit ) {
  
              int l_currentElapsedSeconds = (int) Math.Floor( ( DateTime.Now - l_startTime ).TotalSeconds );
              if ( l_currentElapsedSeconds &gt; l_elapsedSeconds ) {
                  Console.CursorTop = 0;
                  Console.CursorLeft = 0;
                  l_elapsedSeconds = l_currentElapsedSeconds;
  
                  int l_remainingSeconds = 10 - l_elapsedSeconds;
  
                  Console.WriteLine( String.Format( "{0,-80}", "Please select an option within " + l_remainingSeconds + " seconds..." ) );
              }
  
              if ( l_elapsedSeconds &gt;= 10 ) {
                  OptionA();
                  break;
              }
  
              if ( Console.KeyAvailable ) {
                  var l_key = Console.ReadKey( true );
  
                  switch ( l_key.Key ) {
                      case ConsoleKey.D1:
                          OptionA();
                          l_exit = true;
                          break;
  
                      case ConsoleKey.D2:
                          Option2();
                          l_exit = true;
                          break;
  
                      case ConsoleKey.D3:
                          OptionIII();
                          l_exit = true;
                          break;
                  }
              }
  
              if ( !l_exit )
                  // Don't eat all the processor
                  System.Threading.Thread.Sleep( 100);
          }
  
          Console.CursorTop = 7;
          Console.CursorLeft = 0;
  
          Console.Write( "Press any key to continue...");
          Console.ReadKey( true);
  
      }
  
      static void OptionA() {
          Console.CursorTop = 6;
          Console.CursorLeft = 0;
  
          Console.WriteLine( "Option A Selected!");
      }
  
      static void Option2() {
          Console.CursorTop = 6;
          Console.CursorLeft = 0;
  
          Console.WriteLine( "Option 2 Selected!");
      }
  
      static void OptionIII() {
          Console.CursorTop = 6;
          Console.CursorLeft = 0;
  
          Console.WriteLine( "Option III Selected!");
      }
  }
  </code></pre>
  
  <p><sub><strong>Note: This question is not concerned about a timeout... it is about using 0% processor time while waiting for a response (like a windowed application).</strong></sub></p>