I'm having a problem using Console.ReadKey()
with Thread.Sleep()
. I wrote the following method as a replacement for Console.Readline()
with the added functionality of being able to be interrupted.
public static string Readline()
{
Interrupted = false;
ConsoleKeyInfo keyInfo;
string input = "";
do
{
while(!Console.KeyAvailable)
{
Thread.Sleep(20);
if(Interrupted)
{
break;
}
}
if(Interrupted)
{
break;
}
keyInfo = Console.ReadKey(true);
if(keyInfo.Key == ConsoleKey.Backspace)
{
if(input.Length > 0)
{
input = input.Remove(input.Length - 1, 1);
Console.Write("\b \b");
}
}
else
{
input += keyInfo.KeyChar;
Console.Write(keyInfo.KeyChar);
}
}
while(keyInfo.Key != ConsoleKey.Enter);
Console.WriteLine();
return input;
}
The problem here is that calling Thread.Sleep()
causes Console.ReadKey()
to echo the key pressed, even though true
is passed in to Console.ReadKey()
to disable echoing. The key pressed is supposed to be echoed by the Console.Write()
call further down, so what actually happens when the program runs is that each key echoes twice. When I remove the call to Thread.Sleep()
, everything works as it should, however CPU usage shoots up to 100% while it's waiting for Console.KeyAvailable
.
Here's what I've already tried:
Removing the
while(!Console.KeyAvailable)
and placing all the code in the loop, except theThread.Sleep()
and the interrupt check, inside of anif(Console.KeyAvailable)
Adding another
Thread.Sleep()
right before and after the call toConsole.ReadKey()
Removing the
Console.Write()
call that echoes the pressed key. Each key does only echo once, however backspace no longer works.Placing the interrupt checking loop containing the
Thread.Sleep()
in a separate thread and waiting on anAutoResetEvent
in the main loop containing theConsole.ReadKey()
Running the method asynchronously and using
await Task.Delay()
in place ofThread.Sleep()
None of these have fixed the issue. Is there anything I could do to make Console.ReadKey()
work as intended, such as an alternative to Console.ReadKey()
or Thread.Sleep()
? To put it simply, what I need is something that can limit CPU usage while waiting without causing Console.ReadKey()
to echo keypresses when it shouldn't.