I know I can use ReadKey for that but it will freeze the app until user presses a key. Is it possible (in console app) to have some loop running and still be able to react? I can only think of events but not sure how to use them in console.
My idea was that the loop would check for input during each iteration.
Asked
Active
Viewed 6,775 times
6

Ptr
- 149
- 1
- 8
-
Surely you want the app to be in a state of ready to accept user input, so on key press you can do some functionality. Or is this like a press a button to cancel processing?? – jimplode Oct 14 '10 at 08:18
-
Yes but great example is a game - you need to run some loop (enemy movement, whatever) but still register player input – Ptr Oct 14 '10 at 08:22
3 Answers
8
They way I have done this for my own application was to have a dedicated thread that calls into System.Console.ReadKey(true)
and puts the keys pressed (and any other events) into a message queue.
The main thread then services this queue in a loop (in a similar fashion to the main loop in a Win32 application), ensuring that rendering and event processing is all handled on a single thread.
private void StartKeyboardListener()
{
var thread = new Thread(() => {
while (!this.stopping)
{
ConsoleKeyInfo key = System.Console.ReadKey(true);
this.messageQueue.Enqueue(new KeyboardMessage(key));
}
});
thread.IsBackground = true;
thread.Start();
}
private void MessageLoop()
{
while (!this.stopping)
{
Message message = this.messageQueue.Dequeue(DEQUEUE_TIMEOUT);
if (message != null)
{
switch (message.MessageType)
{
case MessageType.Keyboard:
HandleKeyboardMessage((KeyboardMessage) message);
break;
...
}
}
Thread.Yield(); // or Thread.Sleep(0)
}
}

Paul Ruane
- 37,459
- 12
- 63
- 82
1
Have the loop run in separate thread.
class Program
{
private static string input;
public static void Main()
{
Thread t = new Thread(new ThreadStart(work));
input = Console.ReadLine();
}
private static void work()
{
while (input == null)
{
//do stuff....
}
}
}

Itay Karo
- 17,924
- 4
- 40
- 58
1
Try KeyAvailable property starting with .NET Framework 2 through now (current .NET 6 - including .NET Core). A single thread can process in a loop without being blocked.
// loop start
if (Console.KeyAvailable) // Non-blocking peek
{
var key = Console.ReadKey(true);
// process key
}
// continue without stopping
// loop end

Dana Reed
- 59
- 1
- 7