0

I couldn't figure out how to word that question...

In my applications, if the user presses enter before the the ConsoleKeyInfo object is even assigned to Console.ReadKey() it automatically sets it to whatever the user pressed. In fact, it seems to stack because if the user smashes enter 5 times, it will assign it automatically 5 times and this is very bad for me. I've followed this very carefully through the debug process and I'm fairly confident that this is what happens. The window of opportunity in which the user can press enter however many times is created with Thread.Sleep(). I was warned against using it but I thought it would be fine for me because I need everything to stop just for a moment so the user can read a line of text. I'm thinking maybe such an opportunity isn't expected to ever exist? Or maybe I'm interpreting what's going on here incorrectly? I only ask for input on one line of code in the entire application...

1 Answers1

0

If i'm reading what you say correctly, you don't like the way that keypresses when pressed are all queued up, and then only removed when you do Console.Readkey....and this causes you issues when you get repetitions in close proximity.

Below is an attempt to handle the keypress queue in a way that might help - adapt it as necessary. I can't tell if you are just using the keyboard for "option" selection, or for free text input, etc...but I think it can help.

Take a look here:

I've adapted that so that it tries to detect "repeated" keypresses, and it will "ignore them"/"eat them" if they occur together within a certain time span....but will move on, if it is a different keypress.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp6
{
    class Program
    {
        public static void Main()
        {
            ConsoleKeyInfo ckilast = default(ConsoleKeyInfo);
            ConsoleKeyInfo ckicurrent = default(ConsoleKeyInfo);

            Console.WriteLine("\nPress a key to display; press the 'x' key to quit.");

            // Adjust this "window" period, till it feels right

            //TimeSpan tsignorerepeatedkeypresstimeperiod = new TimeSpan(0, 0, 0, 0, 0); // 0 for no extra delay

            TimeSpan tsignorerepeatedkeypresstimeperiod = new TimeSpan(0, 0, 0, 0, 250);

            do
            {
                while (Console.KeyAvailable == false)
                    Thread.Sleep(250); // Loop until input is entered.

                ckilast = default(ConsoleKeyInfo);

                DateTime eatingendtime = DateTime.UtcNow.Add(tsignorerepeatedkeypresstimeperiod); // will ignore any "repeated" keypresses of the same key in the repeat window

                do
                {
                    while (Console.KeyAvailable == true)
                    {
                        ckicurrent = Console.ReadKey(true);

                        if (ckicurrent.Key == ConsoleKey.X)
                            break;

                        if (ckicurrent != ckilast) // different key has been pressed to last time, so let it get handled
                        {
                            eatingendtime = DateTime.UtcNow.Add(tsignorerepeatedkeypresstimeperiod); // reset window period

                            Console.WriteLine("You pressed the '{0}' key.", ckicurrent.Key);

                            ckilast = ckicurrent;

                            continue;
                        }
                    }

                    if (Console.KeyAvailable == false)
                    {
                        Thread.Sleep(50);
                    }

                } while (DateTime.UtcNow < eatingendtime);

            } while (ckicurrent.Key != ConsoleKey.X);
        }
    }
}
Colin Smith
  • 12,375
  • 4
  • 39
  • 47