Search code examples
c#ipcstdoutstdin

Event driven stdin in C#


Does C# provide an event when data is received on the stdin stream for my own process? Something like Process.OutputDataReceived, only I need an event for InputDataReceived.

I've searched high and low, and learned to redirect stdin->stdout, monitor output streams of spawned apps and a ton of other stuff, but nowhere has anyone shown which event is triggered when stdin is recieved. Unless I use a dumb polling loop in main().

// dumb polling loop -- is this the only way? does this consume a lot of CPU?
while ((line = Console.ReadLine()) != null && line != "") {
     // do work
}

Also, I need to get binary data from the stream, something like this:

using (Stream stdin = Console.OpenStandardInput())
using (Stream stdout = Console.OpenStandardOutput())
{
    byte[] buffer = new byte[2048];
    int bytes;
    while ((bytes = stdin.Read(buffer, 0, buffer.Length)) > 0) {
        stdout.Write(buffer, 0, bytes);
    }
}

Solution

  • The polling loop won't consume much CPU, because ReadLine blocks and waits. Put this code in an own worker-thread and raise your event out of it. As far as I know, there is no such feature in .NET.

    EDIT: I was wrong here in the first place. Corrected:

    You can actually read the binary data from stdin, as this SO answer says:

    To read binary, the best approach is to use the raw input stream - here showing something like "echo" between stdin and stdout:

    using (Stream stdin = Console.OpenStandardInput())
    using (Stream stdout = Console.OpenStandardOutput())
    {
        byte[] buffer = new byte[2048];
        int bytes;
        while ((bytes = stdin.Read(buffer, 0, buffer.Length)) > 0) {
            stdout.Write(buffer, 0, bytes);
        }
    }