C# 控制台 readkey 阻塞

问题描述

使用控制台编写服务器程序,服务器和客户端的通信使用异步通信处理,另外控制台可以通过用户输入命令查看响应信息,即控制台需要满足一边通信一边可以接收用户输入,但是问题出现了,控制台在等待用户输入的时候(偶尔)会处于阻塞状态,此时服务器无法接收到客户端消息。

解决方案

使用Console.KeyAvailable属性解决Console.ReadKey() 阻塞问题,以下是项目中的代码

ConsoleKeyInfo cki = new ConsoleKeyInfo();      
            do
            {           
                if (Console.KeyAvailable)
                {
                    cki = Console.ReadKey(false);
                    Console.WriteLine("You pressed the '{0}' key.", cki.Key);
                    switch (cki.Key)
                    {
                        case ConsoleKey.C:
                            //do something
                            break;
                        case ConsoleKey.E:
                            //do something
                            break;
                        case ConsoleKey.Q:
                            //do something
                            break;
                        default:                            
                            break;
                    }
                }
            }
            while (cki.Key != ConsoleKey.Q);

知识扩展

在控制台程序中,几种读取输入方法的比较

方法 Read() ReadKey() ReadKey(Boolean) ReadLine()
功能 从标准输入流读取下一个字符 获取用户按下的下一个字符或功能键。 按下的键显示在控制台窗口中。 获取用户按下的下一个字符或功能键。 按下的键可以选择显示在控制台窗口中。True:不显示在控制台,False:显示在控制台 从标准输入流读取下一行字符
返回值 输入流中的下一个字符;如果当前没有更多的字符可供读取,则为负一 (-1) 一个 ConsoleKeyInfo对象,描述 ConsoleKey 常数和对应于按下的控制台键的 Unicode 字符(如果存在这样的字符) 同上 输入流中的下一行字符;如果没有更多的可用行,则为 空引用(在 Visual Basic 中为 Nothing)。
备注 在键入输入字符时,Read 方法会阻止其返回;该方法在您按 Enter 键时终止。使用 ReadLine 方法或使用 KeyAvailable属性和 ReadKey方法比使用 Read 方法更可取 ConsoleKeyInfo 类型不应由用户创建。实际上,它作为调用 Console.ReadKey方法的响应返回给用户 同上 行被定义为后跟回车符(十六进制 0x000d)、换行符(十六进制 0x000a)或[Environment.NewLine 属性值的字符序列。返回的字符串不包含终止字符。

使用Console.KeyAvailable属性解决阻塞

属性值
如果按键操作可用,则为 true;否则为 false。

备注
属性值会立即返回,也就是说,KeyAvailable 属性不会为等待按键操作可用而阻止输入。
请只将 KeyAvailable 属性与ReadKey 方法结合使用,而不是与Read 或 ReadLine 方法结合使用。

示例

// This example demonstrates the Console.KeyAvailable property.
using System;
using System.Threading;

class Sample 
{
    public static void Main() 
    {
    ConsoleKeyInfo cki = new ConsoleKeyInfo();

    do {
        Console.WriteLine("\nPress a key to display; press the 'x' key to quit.");

// Your code could perform some useful task in the following loop. However, 
// for the sake of this example we'll merely pause for a quarter second.

        while (Console.KeyAvailable == false)
            Thread.Sleep(250); // Loop until input is entered.
        cki = Console.ReadKey(true);
        Console.WriteLine("You pressed the '{0}' key.", cki.Key);
        } while(cki.Key != ConsoleKey.X);
    }
}
/*
This example produces results similar to the following text:

Press a key to display; press the 'x' key to quit.
You pressed the 'H' key.

Press a key to display; press the 'x' key to quit.
You pressed the 'E' key.

Press a key to display; press the 'x' key to quit.
You pressed the 'PageUp' key.

Press a key to display; press the 'x' key to quit.
You pressed the 'DownArrow' key.

Press a key to display; press the 'x' key to quit.
You pressed the 'X' key.
*/

你可能感兴趣的:(C# 控制台 readkey 阻塞)