39

I want a non-blocking read function from console. How do I write that in C#?

steve
  • 1,021
  • 1
  • 14
  • 29
Masoud
  • 1,354
  • 6
  • 18
  • 30
  • @Mitch Wheat: Isn't ReadKey blocking? – jgauffin Apr 11 '11 at 11:36
  • @Mitch you need to combine at least `KeyAvailable` and `ReadKey`. And I'm still not sure if that's the right thing to do, and how it interacts with redirected input or dead keys. So it's certainly not a trivial question. – CodesInChaos Apr 11 '11 at 11:37
  • @Masoud Have you read, e.g., http://stackoverflow.com/questions/3738731/feed-input-to-console-readkey? It might be you are asking the wrong question for your problem... – RB. Apr 11 '11 at 11:39
  • What do you want to use that non blocking read for? The correct way to solve this might depend on those additional details. – CodesInChaos Apr 11 '11 at 11:42
  • Who said the OP asked about reading console input? “Non-blocking read” is a very broad topic. The quality of the question is similar to “I want a program for sending email.” Hence “not a real question” is IMO the best category for closing it. – Ondrej Tucny Apr 11 '11 at 11:55
  • 2
    @Ondrej To quote the OP: "from console" – CodesInChaos Apr 11 '11 at 12:02
  • @CodeInChaos “from console” can easily mean “from a console application”. IMO the question is highly indeterminate. – Ondrej Tucny Apr 11 '11 at 12:09

2 Answers2

78

Richard Dutton has a solution on his blog:

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  
} 
Community
  • 1
  • 1
odrm
  • 5,149
  • 1
  • 18
  • 13
  • the `ConsoleKeyInfo` contains the field `KeyChar` which represents the `char` representation, which might be what the OP wants. – CodesInChaos Apr 11 '11 at 11:35
  • 17
    @spender That's why there is the `// Do something more useful` comment in there. – CodesInChaos Apr 11 '11 at 11:48
  • 6
    This answer is perfect for what I wanted. I have a program running an infinite loop and outputting stuff, but I want to be able able to input commands via keyboard characters without blocking the loop. – damccull Aug 13 '14 at 19:35
  • 1
    I think this is the real answer the OP was searching for, and probably the one that should be marked as correct. In any case, it did what I was searching for. Thanks. – Alberto Oct 12 '16 at 10:52
  • 1
    This doesn't actually read from stdin when it's not Console! – alamar Jul 08 '17 at 17:30
  • Link to Blog is dead – Liam May 20 '21 at 10:50
  • I'm working with a redirected standard input, and as of https://stackoverflow.com/a/7373154/613014 and my experiences, ReadKey does not do what the heading of the question asks for - reading standard input. – Eike Aug 09 '21 at 12:53
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);
spender
  • 117,338
  • 33
  • 229
  • 351
  • Didn't you forget the count parameter? – CodesInChaos Apr 11 '11 at 12:01
  • 1
    When will your `EndRead` be triggered? I think only if you arrive either at the end of the stream, or when the buffer is full, and not if only a few characters of input are available. – CodesInChaos Apr 11 '11 at 12:11
  • Ah. You are sort of right. Actually, the stream seems to be flushed only on carriage return. Your method is looking better and better! – spender Apr 11 '11 at 12:18
  • 1
    Doesn't seem to work (hangs) if there's nothing to read. Blocking. – alamar Jul 08 '17 at 17:42