按键是否为队列排队?

时间:2017-04-22 03:38:51

标签: c# keyboard console-application keyboard-events

我无法弄清楚如何说出这个问题......

在我的应用程序中,如果用户在将ConsoleKeyInfo对象分配给Console.ReadKey()之前按Enter键,它会自动将其设置为用户按下的任何内容。事实上,它似乎堆叠,因为如果用户粉碎输入5次,它将自动分配5次,这对我来说非常糟糕。我在调试过程中非常谨慎地遵循了这一点,并且我非常确信这就是发生的事情。使用Thread.Sleep()创建用户可以多次按Enter键的机会窗口。我被警告不要使用它,但我认为这对我来说没问题,因为我需要一切停下来让用户可以阅读一行文字。我想也许这样的机会不会存在?或者我可能会错误地解释这里发生的事情?我只要求在整个应用程序中输入一行代码......

1 个答案:

答案 0 :(得分:0)

如果我正在读你正确的说法,你不喜欢按下时按键的方式全部排队,然后只有当你执行Console.Readkey时删除....这会导致你的问题当你在附近重复时。

下面是尝试以可能有用的方式处理按键队列 - 根据需要进行调整。我不知道你是否只是使用键盘进行“选项”选择,或者用于自由文本输入等...但我认为它可以提供帮助。

看看这里:

我已经适应了它,以便它试图检测“重复”的按键,并且如果它们在一定的时间跨度内一起出现,它将“忽略它们”/“吃它们”......但是如果它们继续前进,这是一个不同的按键。

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);
        }
    }
}