简体   繁体   English

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

[英]NET C# Console application not detecting key presses correctly

I have a console program.我有一个控制台程序。 Its purpose is to check if the keys F1-F2 is pressed in a loop and then send out a message if one of those keys is pressed but I cannot get it to work properly.它的目的是检查 F1-F2 键是否在循环中被按下,然后如果按下其中一个键但我无法让它正常工作,则发送一条消息。 The way I detect or listen for keys is if(Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.F2) .我检测或监听键的方式是if(Console.KeyAvailable && Console.ReadKey(true).Key == ConsoleKey.F2) Console.ReadKey(true).Key == ConsoleKey.F2 Blocks the execution and waits for input so I have to put Console.KeyAvailable in front of it, so the loop can just continue and check if the next key is pressed. Console.ReadKey(true).Key == ConsoleKey.F2阻止执行并等待输入,所以我必须将Console.KeyAvailable放在它前面,这样循环就可以继续并检查是否按下了下一个键。 I did this in a while(true) loop, in Main() until I reached out to one of my friends who told me to put the whole thing in a standalone thread.我在Main()中的while(true)循环中完成了此操作,直到我联系了我的一位朋友,他告诉我将整个事情放在一个独立的线程中。 I did just that which made almost no difference (besides some cleaner code).我做了几乎没有什么区别的事情(除了一些更简洁的代码)。

I read about Keyboard.GetKeyStates(Key) method, but turns out this doesn't work in a C# NET Console app.我阅读了有关Keyboard.GetKeyStates(Key)方法的信息,但事实证明这在 C# NET 控制台应用程序中不起作用。 Currently, the loop doesn't even want to go past checking if F1 is pressed unless I make another separate thread to check if F2 is pressed, which results in it still not working and having to spam the keys to get the if s to do anything in the first place.目前,循环甚至不想 go 过去检查 F1 是否被按下,除非我创建另一个单独的线程来检查 F2 是否被按下,这导致它仍然无法正常工作并且不得不发送垃圾邮件来获取if s首先是任何东西。

Code:代码:

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

Not sure why do you need threads here.不知道为什么在这里需要线程。

  1. Run the while loop and check if there is KeyAvailable .运行 while 循环并检查是否存在KeyAvailable Only if the key is available (a user pressed something), use the ReadKey function that blocks the thread.仅当密钥可用(用户按下某些东西)时,才使用阻塞线程的 ReadKey function。

  2. Provide a key that breaks the loop (ESC in this case).提供一个打破循环的键(在本例中为 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);
        }
    }
}

A key point to understand is that ReadKey() consumes the keypress.要理解的关键点是ReadKey()消耗按键。 So after checking for F1 in the first if statement, the KeyAvailable() call in the second if statement will return false and therefore you'll never detect anything but F1.因此,在第一个if语句中检查 F1 后,第二个if语句中的KeyAvailable()调用将返回false ,因此您将永远检测不到 F1 之外的任何内容。

You want to wait until there is a key available, and then call ReadKey() ONCE, using that same return value in multiple checks:您想等到有可用的密钥,然后调用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");
            }
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM