11

I'm trying to run a python script from C# and I want to get the output line by line and not at the end. I feel like I'm missing something important, but don't know what. This is what I have so far:

static void Main(string[] args)
{
    var cmd = "C:/Users/user/Documents/script.py";
    var process = new Process
    {
        StartInfo = new ProcessStartInfo
        {
            FileName = "C:/Users/user/AppData/Local/Programs/Python/Python36/python.exe",
            Arguments = cmd,
            UseShellExecute = false,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            CreateNoWindow = true
        },
        EnableRaisingEvents = true
    };
    process.ErrorDataReceived += Process_OutputDataReceived;
    process.OutputDataReceived += Process_OutputDataReceived;

    process.Start();
    process.BeginErrorReadLine();
    process.BeginOutputReadLine();
    process.WaitForExit();
    Console.Read();
}

static void Process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
    Console.WriteLine(e.Data);
}

And the python code:

import time

for i in range(5):
    print("Hello World " + str(i))
    time.sleep(1)
3
  • 1
    Are we to assume that you are getting output, but you're getting it all at once? This is not stated in the question. Commented Nov 19, 2018 at 18:34
  • I am getting output, but at the end of the 5 seconds. Commented Nov 19, 2018 at 18:35
  • 1
    By default print does not flush the output. There are several ways of doing that, depending on your python version. See: stackoverflow.com/questions/230751/… Commented Nov 19, 2018 at 18:37

1 Answer 1

15

change your python code to the following:

import time
import sys
for i in range(5):
    print("Hello World " + str(i))
    sys.stdout.flush()
    time.sleep(1)

or just edit your c# code and use -u switch:

var cmd = "-u C:/Users/user/Documents/script.py";

When standard output it was being redirected, the event in C# wasn't being raised when a line was written on console because there were no calls to stdout.flush;

Putting a stdout.flush() statement after each print statement made the events fire as they should and C# now captures the output as it comes.

Or you could just use -u switch.

Sign up to request clarification or add additional context in comments.

3 Comments

This works perfectly. Apparently I didn't know about the flushing mechanism.
Note that if you don't want to modify the python code, there are alternative ways of accomplishing this. See my link under your question. the command-line argument -u will use unbuffered streams.
-u works perfect

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.