Console.ReadKey与Thread.Sleep意外地回应

时间:2018-04-24 23:03:15

标签: c# .net multithreading

我在Console.ReadKey()使用Thread.Sleep()时遇到问题。我编写了以下方法作为Console.Readline()的替代,增加了可以被中断的功能。

public static string Readline()
{
    Interrupted = false;
    ConsoleKeyInfo keyInfo;
    string input = "";
    do
    {
        while(!Console.KeyAvailable)
        {
            Thread.Sleep(20);

            if(Interrupted)
            {
                break;
            }
        }

        if(Interrupted)
        {
            break;
        }

        keyInfo = Console.ReadKey(true);
        if(keyInfo.Key == ConsoleKey.Backspace)
        {
            if(input.Length > 0)
            {
                input = input.Remove(input.Length - 1, 1);
                Console.Write("\b \b");
            }
        }
        else
        {
            input += keyInfo.KeyChar;
            Console.Write(keyInfo.KeyChar);
        }
    }
    while(keyInfo.Key != ConsoleKey.Enter);
    Console.WriteLine();

    return input;
}

这里的问题是调用Thread.Sleep()会导致Console.ReadKey()回显按下的键,即使true传入Console.ReadKey()以禁用回显。按下的键是假设Console.Write()调用进一步向下呼叫,所以当程序运行时实际发生的是每个键回响两次。当我删除对Thread.Sleep()的调用时,一切正常,但在等待Console.KeyAvailable时,CPU使用率会高达100%。

以下是我已经尝试过的内容:

  • 删除while(!Console.KeyAvailable)并将所有代码放在循环中,Thread.Sleep()

  • 内的if(Console.KeyAvailable)和中断检查除外
  • 在致电Thread.Sleep()

    之前和之后添加另一个Console.ReadKey()
  • 删除回显按下的键的Console.Write()来电。每个键回显一次,但退格不再有效。

  • 将包含Thread.Sleep()的中断检查循环放在一个单独的线程中,等待包含AutoResetEvent

    的主循环中的Console.ReadKey()
  • 异步运行方法并使用await Task.Delay()代替Thread.Sleep()

这些都没有解决问题。我可以做些什么让Console.ReadKey()按预期工作,例如替代Console.ReadKey()Thread.Sleep()?简单来说,我需要的是可以在等待时限制CPU使用而不会导致Console.ReadKey()在不应该响应按键的情况下回应按键的情况。

0 个答案:

没有答案