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.
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 Thread.Sleep 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.
In a Windows application (Windows Forms or WPF) 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, SAS Enterprise Guide and SQL Server Management Studio use practically 0% of the processor when they are idle. Can I get the same effect with my console application?
The Thread.Sleep is working, but, as I said, I want to know if there's a better way.
Here's the source 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 > 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 >= 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!");
}
}
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).
There are two ways to display messages in the console: System. out. println () and System. out.
Console-based applications include Alpine (an e-mail client), cmus (an audio player), Irssi (an IRC client), Lynx (a web browser), Midnight Commander (a file manager), Music on Console (an audio player), Mutt (an e-mail client), nano (a text editor), ne (a text editor), newsbeuter (an RSS reader), and ranger (a file ...
A console application facilitates the reading and writing of characters from a console - either individually or as an entire line. It is the simplest form of a C# program and is typically invoked from the Windows command prompt.
The "message pump" is a core part of any Windows program that is responsible for dispatching windowing messages to the various parts of the application. This is the core of Win32 UI programming.
You could start a thread that reads key presses in the background. Add the keys to a blocking queue and wait in the main thread for the queue to be filled, e.g.
var queue = new BlockingCollection<ConsoleKeyInfo>();
new Thread(() =>
{
while (true) queue.Add(Console.ReadKey(true));
})
{ IsBackground = true }.Start();
Console.Write("Welcome! Please press a key: ");
ConsoleKeyInfo cki;
if (queue.TryTake(out cki, TimeSpan.FromSeconds(10))) //wait for up to 10 seconds
{
Console.WriteLine();
Console.WriteLine("You pressed '{0}'", cki.Key);
}
else
{
Console.WriteLine();
Console.WriteLine("You did not press a key");
}
Both the background thread and the main thread will sleep (utilize 0% processor time) while they're waiting for ReadKey and TryTake to return respectively.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With