C#中的非阻塞标准I/O读取

40

我想要一个非阻塞的从控制台读取函数。我该如何在C#中编写?


@Mitch Wheat:ReadKey 是阻塞的吗? - jgauffin
@Mitch,您需要至少将KeyAvailableReadKey结合起来。而且我仍然不确定这是否是正确的做法,以及它如何与重定向输入或死键交互。因此,这绝对不是一个简单的问题。 - CodesInChaos
你想用非阻塞读取做什么?正确的解决方法可能取决于这些额外的细节。 - CodesInChaos
2
@Ondrej 引用原帖中的话:“来自控制台” - CodesInChaos
@CodeInChaos中的“from console”很容易意味着“从控制台应用程序”。在我看来,这个问题非常不确定。 - Ondrej Tucny
显示剩余2条评论
2个回答

78

Richard Dutton他的博客上提供了一种解决方案:

while (true)  
{  
    if (Console.KeyAvailable)  
    {  
        ConsoleKeyInfo key = Console.ReadKey(true);  
        switch (key.Key)  
        {  
            case ConsoleKey.F1:  
                Console.WriteLine("You pressed F1!");  
                break;  
            default:  
                break;  
        }  
    }  
    // Do something more useful  
} 

17
这就是为什么有“// Do something more useful”这条注释的原因。 - CodesInChaos
7
这个回答完全符合我的要求。我有一个程序正在运行一个无限循环并输出一些内容,但我希望能够通过键盘字符输入命令而不会阻塞循环。 - damccull
1
我认为这是原帖作者正在寻找的真正答案,也可能是应该标记为正确答案的答案。无论如何,它解决了我正在寻找的问题。谢谢。 - Alberto
2
当控制台不是时,它实际上并没有从标准输入读取! - alamar
我正在使用重定向的标准输入,并且根据 https://stackoverflow.com/a/7373154/613014 和我的经验,ReadKey 不会执行问题标题所要求的读取标准输入的操作。 - Eike
显示剩余2条评论

8
var buf=new byte[2048];
var inputStream=Console.OpenStandardInput(); //dispose me when you're done
inputStream.BeginRead(buf,0,buf.Length,ar=>{
    int amtRead=inputStream.EndRead(ar);
    //buf has what you need. You'll need to decode it though
},null);

你没有忘记 count 参数吗? - CodesInChaos
1
你的 EndRead 什么时候会被触发?我认为只有当你到达流的末尾或缓冲区已满时才会触发,而不是仅在输入的几个字符可用时触发。 - CodesInChaos
啊,你有点对。实际上,流似乎只在回车时被刷新。你的方法看起来越来越好了! - spender
1
如果没有可读内容,似乎无法正常工作(挂起)。 阻塞。 - alamar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接