Reading Key Press in Console App

2019-06-10 06:13发布

问题:

I'm writing a small application which will wait for a key press, then perform an action based on what key is pressed. For example, if no key is pressed, it will just continue waiting, if key 1 is pressed, it will perform action 1, or if key 2 is pressed it will perform action 2. I have found several helpful posts so far, this one being an example. From this, I have the following code so far.

do
{
    while (!Console.KeyAvailable)
    {
        if (Console.ReadKey(true).Key == ConsoleKey.NumPad1)
        {
            Console.WriteLine(ConsoleKey.NumPad1.ToString());
        }
        if (Console.ReadKey(true).Key == ConsoleKey.NumPad2)
        {
            Console.WriteLine(ConsoleKey.NumPad1.ToString());
        }
    }

} while (Console.ReadKey(true).Key != ConsoleKey.Escape);

There's a couple of issue with this, which you may have guessed already.

1) Using the ReadKey to detect which key is pressed results in a temporary pause, meaning the key will have to be pressed. I really need to find a way to avoid this. Possibly using KeyAvailable, but I'm not sure how you can use this to detect which key has been pressed - any ideas?

2) For some reason, the Escape key does not escape out of the application. It does if I remove the if statements, however running the code as is above does not let me exit the application using the designated key - any ideas?

回答1:

The reason for the behavior is simple:

You get inside the nested loop as long as there is no key pressed. Inside you are waiting for a key and read it - So again no key is available. even if you press escape, you are still inside the nested loop and never get out of it.

What you should of done is loop until you have a key available, then read it and check its value:

ConsoleKey key;
do
{
    while (!Console.KeyAvailable)
    {
        // Do something, but don't read key here
    }

    // Key is available - read it
    key = Console.ReadKey(true).Key;

    if (key == ConsoleKey.NumPad1)
    {
        Console.WriteLine(ConsoleKey.NumPad1.ToString());
    }
    else if (key == ConsoleKey.NumPad2)
    {
        Console.WriteLine(ConsoleKey.NumPad1.ToString());
    }

} while (key != ConsoleKey.Escape);