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