为什么在过程完成后出现重定向的标准输出?

时间:2019-02-22 18:23:27

标签: c# python process

我正在使用Visual Studio 2015和.NET Framework 4.7.2。我已经建立了一个简单的测试程序,该程序在C#中执行一个外部程序。该程序是一个Python脚本,它仅每0.5秒将一些字符串输出到stdout。我想在我的C#应用​​程序中读取此子进程的标准输出。

该程序基本上可以运行,但是我只是在子进程退出前不久获得了Python脚本的输出。为了获得更响应的行为,我需要更改什么,即Python脚本将其写入标准输出后每0.5秒获取一次输出?

这是我的C#代码:

public class Program {

    private Process process;

    public static void Main(string[] args) {
        new Program().init();
    }

    private void init() {
        startPythonProcess();
        process.WaitForExit();
        Console.ReadLine();
    }

    private void startPythonProcess() {
        if(process==null) {
            try {

                Console.WriteLine("Starting Python process ...");

                string filepath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase).Substring(6);
                process = new Process();

                ProcessStartInfo startInfo = new ProcessStartInfo();
                startInfo.CreateNoWindow = false;
                startInfo.UseShellExecute = false;
                startInfo.WorkingDirectory = filepath;
                startInfo.FileName = "python.exe";
                //startInfo.WindowStyle = ProcessWindowStyle.Normal;
                startInfo.RedirectStandardInput = false;
                startInfo.RedirectStandardOutput = true;
                startInfo.RedirectStandardError = true;
                startInfo.Arguments = string.Format("{0}", Path.Combine(filepath, "test.py"));

                process.StartInfo = startInfo;
                process.OutputDataReceived += OutputDataReceivedEventHandler;
                process.ErrorDataReceived += ErrorDataReceivedEventHandler;

                process.Start();

                process.BeginOutputReadLine();
                process.BeginErrorReadLine();

            } catch(Exception ex) {
                Console.WriteLine("Could not start Python process: " + ex.Message);
            }
        }
    }

    public void OutputDataReceivedEventHandler(object sender, DataReceivedEventArgs args) {
        Console.WriteLine("[PYTHON] INFO: {0}", args.Data);
    }

    public void ErrorDataReceivedEventHandler(object sender, DataReceivedEventArgs args) {
        Console.WriteLine("[PYTHON] ERROR: {0}", args.Data);
    }

}

这是我的Python脚本:

import time
import sys
import logging


logging.basicConfig(level=logging.ERROR)

if __name__ == '__main__':
    count = 0
    while True:
        print('PYTHON: {}'.format(count))
        time.sleep(0.5)
        count+=1
        if count>=25:
            break

更新:我上传了小型项目here

1 个答案:

答案 0 :(得分:2)

print函数采用一个 flush 参数,该参数控制是否刷新缓冲的输出。

flush 的默认值为False,这意味着print所写入的文件(例如,sys.stdout)都控制刷新。

flush 设置为True以强制立即打印。

print('PYTHON: {}'.format(count), flush=True)