【问题标题】:Reading Key Press in Console App在控制台应用程序中读取按键
【发布时间】:2018-04-06 22:44:30
【问题描述】:

我正在编写一个小应用程序,它将等待按键,然后根据按下的键执行操作。例如,如果没有按下任何键,它将继续等待,如果按下键 1,它将执行动作 1,或者如果按下键 2,它将执行动作 2。到目前为止,我发现了一些有用的帖子,@987654321 @是一个例子。由此,到目前为止,我有以下代码。

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

这有几个问题,您可能已经猜到了。

1) 使用ReadKey 检测按下了哪个键会导致暂时暂停,这意味着必须按下该键。我真的需要找到一种方法来避免这种情况。可能使用KeyAvailable,但我不确定如何使用它来检测按下了哪个键 - 有什么想法吗?

2) 出于某种原因,Escape 键不会从应用程序中逸出。如果我删除 if 语句,它会这样做,但是按上述方式运行代码不会让我使用指定的键退出应用程序 - 有什么想法吗?

【问题讨论】:

    标签: c# .net console-application listener


    【解决方案1】:

    行为的原因很简单:

    只要没有按键,你就会进入嵌套循环。 在里面你正在等待钥匙并阅读它 - 所以再次没有钥匙可用。 即使你按下了退出,你仍然在嵌套循环中并且永远不会离开它。

    你应该做的是循环直到你有一个可用的密钥,然后读取它并检查它的值:

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

    【讨论】:

    • 这正是我想要的,它帮助我理解KeyAvailable 正在做什么——它循环(等待),而没有可用的密钥。一旦有可用的密钥,它就会中断循环,并继续检查密钥。非常感谢!
    • 坐在那个紧凑的内部while循环中似乎不是一个好主意。为什么不把所有代码放在一个 if 语句中并消除内部 while 循环。 do { if (Console.KeyAvailable) { key = Console.ReadKey(true).Key; ...} } while (key != ConsoleKey.Escape);。要考虑的另一件事是,直接在 ReadKey 调用上引用 Key 属性会导致您丢失有关按键的其他信息,例如还按下了哪些修饰键(Ctrl、Alt、Shift)。
    • 您说得很好@ChrisDunaway,但在您的示例中,变量key 仅在按下键后才被赋值。因此,不可能使用未定义的标准构造一个 do-while 循环。我想你总是可以给它分配一个临时值来启动循环(?),但这看起来很混乱 - 更混乱(虽然可能不像常量 while 循环那样混乱)......如果我误解了,请更新我。谢谢
    • 您仍将在循环外定义key 变量,因为它不会等于ConsoleKey.Escape。如果有可用的密钥,您只需拨打ReadKey。只要按下一个键,下一次检查KeyAvailable 就会为真并输入 if 语句。这有意义吗?
    猜你喜欢
    • 2012-08-28
    • 2023-03-14
    • 2015-08-17
    • 1970-01-01
    • 1970-01-01
    • 2010-11-18
    • 2016-08-21
    • 1970-01-01
    相关资源
    最近更新 更多