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.
-
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– jimplode2010-10-14 08:18:42 +00:00Commented Oct 14, 2010 at 8:18
-
Yes but great example is a game - you need to run some loop (enemy movement, whatever) but still register player inputPtr– Ptr2010-10-14 08:22:47 +00:00Commented Oct 14, 2010 at 8:22
Add a comment
|
3 Answers
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)
}
}
1 Comment
Ptr
Hmm I see, so I guess no easy way how to that. Thanks
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