【问题标题】:NET C# Console application not detecting key presses correctlyNET C# 控制台应用程序未正确检测按键
【发布时间】:2020-11-29 23:25:34
【问题描述】:

我有一个控制台程序。它的目的是检查 F1-F2 键是否在循环中被按下,然后在按下这些键之一但我无法让它正常工作时发送消息。我检测或监听键的方式是if(Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.F2)Console.ReadKey(true).Key == ConsoleKey.F2 阻止执行并等待输入,所以我必须将Console.KeyAvailable 放在它前面,这样循环才能继续并检查是否按下了下一个键。我在while(true) 循环中执行此操作,在Main() 中,直到我联系了我的一位朋友,他告诉我将整个事情放在一个独立的线程中。我做了几乎没有什么区别的事情(除了一些更简洁的代码)。

我读到了Keyboard.GetKeyStates(Key) 方法,但事实证明这在 C# NET 控制台应用程序中不起作用。目前,循环甚至不想检查 F1 是否被按下,除非我创建另一个单独的线程来检查 F2 是否被按下,这导致它仍然无法工作并且必须发送垃圾邮件来获取 ifs首先要做任何事情。

代码:

class Program
    {
        public static void Main()
        {
            Thread ThreadObj = new Thread(F1); //Creating the Thread    
            ThreadObj.Start(); //Starting the Thread    

        }
        static void F1()
        {
            Console.WriteLine("Thread Started");
            while (true)
            {
                if (Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.F1)
                {
                    Console.WriteLine("F1");
                }
                if (Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.F2)
                {
                    Console.WriteLine("F2");
                }
                Thread.Sleep(10);
            }
        }
    }

【问题讨论】:

    标签: c# windows console console-application


    【解决方案1】:

    不知道为什么这里需要线程。

    1. 运行while循环并检查是否有KeyAvailable。仅当键可用(用户按下某物)时,才使用阻塞线程的 ReadKey 函数。

    2. 提供一个打破循环的键(在本例中为 ESC)。

       static void Main(string[] args)
       {
           Console.WriteLine("Press ESC to quit.");
      
           ConsoleKey key;
           do
           {
               while (!Console.KeyAvailable)
               {
                   // Do something
               }
      
               key = Console.ReadKey(true).Key;
      
               if(key == ConsoleKey.Escape)
               {
                   break;
               }
               else if (key == ConsoleKey.F12 || key == ConsoleKey.F11)
               {
                   Console.WriteLine("F12 or F11 pressed");
               }
      
           } while (true);
       }
      

    【讨论】:

    • 这很聪明!谢谢你!
    【解决方案2】:

    要理解的关键点是ReadKey() 消耗按键。因此,在第一个 if 语句中检查 F1 后,第二个 if 语句中的 KeyAvailable() 调用将返回 false,因此您将永远检测不到 F1。

    您想等到有可用的密钥,然后调用ReadKey() ONCE,在多次检查中使用相同的返回值:

            while (true)
            {
    
                // wait for a keypress
                while (!Console.KeyAvailable)
                {
                    Thread.Sleep(100);
                }
    
                ConsoleKeyInfo cki = Console.ReadKey(true); // call ReadKey() once...
    
                // ...and use "cki" multiple times
                // (note there are no more ReadKey() calls below)
                if (cki.Key == ConsoleKey.F1)
                {
                    Console.WriteLine("F1");
                }
                else if (cki.Key == ConsoleKey.F2)
                {
                    Console.WriteLine("F2");
                }
            }
    

    【讨论】:

      【解决方案3】:
      using System;
      
      using System.Threading;
      
      class Program
      
      {
      
          public static void Main()
      
          {
              Thread ThreadObj = new Thread(F1); //Creating the Thread    
              ThreadObj.Start(); //Starting the Thread
      
          }
          static void F1()
          {
              Console.WriteLine("Thread Started");
              while (true)
              {
                  if (Console.ReadKey(true).Key == ConsoleKey.F1)
                  {
                      Console.WriteLine("F1");
                  }
                  if (Console.ReadKey(true).Key == ConsoleKey.F2)
                  {
                      Console.WriteLine("F2");
                  }
                  Thread.Sleep(10);
              }
          }
      }
      

      【讨论】:

      • ReadKey 使用密钥,因此您的提交行为不端,因此无法回答问题。
      猜你喜欢
      • 2012-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-16
      • 2023-03-14
      • 2013-12-07
      相关资源
      最近更新 更多