NET C# 控制台应用程序未正确检测按键

NET C# Console application not detecting key presses correctly

我有一个控制台程序。它的目的是检查是否循环按下 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 是否被按下,这导致它仍然无法正常工作并且不得不向按键发送垃圾邮件以获取 if首先要做任何事情。

代码:

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

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

  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);
     }
    
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() 消耗按键。因此,在第一个 if 语句中检查 F1 之后,第二个 if 语句中的 KeyAvailable() 调用将 return false 因此您永远不会检测到任何东西但是 F1.

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

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