C# Realtime standard output/error capture of a process

Viewed 1187

I'm developing a C# application and I need to run an external console process (for example a python script) and receive the output data of the script in real-time. The python script is something like this:

import time
while 1:
    print("Hi Foo!")
    time.sleep(.3)

The following C# code prints the python script output on the C# console in real-time:

static void Main(string[] args)
{
    using (Process process = new Process())
    {
        process.StartInfo.FileName = "python.exe";
        process.StartInfo.Arguments = "test.py";
        process.StartInfo.UseShellExecute = false;
        process.Start();
        process.WaitForExit();
    }
}

However, when I try to capture the output data and write them on the console manually, I fail. The recommended solution according to other posts is something like this, but it doesn't work:

static void Main(string[] args)
{
    using (Process process = new Process())
    {
        process.StartInfo.FileName = "python.exe";
        process.StartInfo.Arguments = "test.py";
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.EnableRaisingEvents = true;
        process.OutputDataReceived += (s, e) => Console.WriteLine(e.Data);
        process.Start();
        process.BeginOutputReadLine();
        process.WaitForExit();
    }
}

The process.StandardOutput.ReadToEnd() works in blocking mode waiting for the process to exit and returns the whole output all at once. What exactly is the problem with the real-time output capturing and how can I fix it?

1 Answers
        using (var process = new Process())
        {
            process.StartInfo.FileName = @"python.exe";
            process.StartInfo.Arguments = "-u test.py";
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.UseShellExecute = false;
            process.Start();

            while (!process.StandardOutput.EndOfStream)
            {
                string line = process.StandardOutput.ReadLine();
                Console.WriteLine(line);
                // do something with line
            }
            process.WaitForExit();
            Console.Read();
        }
Related