C#调用cmd执行Python脚本无法实时获取输出如何解决
C#调用CMD执行Python脚本无法实时获取输出的解决方案
问题根因
Python标准输出默认采用自适应缓冲策略:当输出到交互式终端时使用行缓冲,每打印一行就立刻刷出内容;当输出被重定向到管道时(比如被C#程序接收),会自动切换为块缓冲,只有缓冲区填满或者进程完全退出时才会一次性输出所有内容。这就是手动在CMD执行脚本可以实时输出、但C#调用时输出延迟的核心原因。
解决方案
两种方案二选一即可:
方案1:修改Python代码,主动刷新输出
无需改动C#代码,在Python的print方法中添加flush=True参数强制立刻刷新输出:
import time time.sleep(5) # Sleep for 5 seconds print("hello", flush=True) time.sleep(10) # Sleep for 10 seconds print("hello", flush=True) time.sleep(15) # Sleep for 15 seconds print("hello", flush=True) time.sleep(1) # Sleep for 1 seconds
如果不想逐行修改print参数,也可以在脚本开头全局配置行缓冲:
import sys sys.stdout.reconfigure(line_buffering=True)
方案2:修改C#调用参数,无需改动Python代码
启动Python解释器时添加-u参数,强制Python标准输入输出使用无缓冲模式,直接修改C#中执行脚本的行即可:
把原代码中的
cmdProcess.StandardInput.WriteLine("py test.py");
替换为
cmdProcess.StandardInput.WriteLine("py -u test.py");
可选优化:直接启动Python进程(无需嵌套CMD)
嵌套一层cmd.exe没有实际作用,直接启动Python进程可以减少中间层,降低异常概率,优化后的C#代码示例:
private void backgroundWorker_sizzer_DoWork(object sender, DoWorkEventArgs e) { ProcessStartInfo pyStartInfo = new ProcessStartInfo(); pyStartInfo.FileName = @"py.exe"; // 加-u参数启用无缓冲,指定脚本路径 pyStartInfo.Arguments = "-u C:\\Users\\test.py"; pyStartInfo.RedirectStandardOutput = true; pyStartInfo.RedirectStandardError = true; pyStartInfo.UseShellExecute = false; pyStartInfo.CreateNoWindow = true; pyStartInfo.WorkingDirectory = @"C:\\Users\\"; Process pyProcess = new Process(); pyProcess.StartInfo = pyStartInfo; pyProcess.ErrorDataReceived += cmd_Error; pyProcess.OutputDataReceived += cmd_DataReceived; pyProcess.EnableRaisingEvents = true; pyProcess.Start(); pyProcess.BeginOutputReadLine(); pyProcess.BeginErrorReadLine(); pyProcess.WaitForExit(); }
内容的提问来源于stack exchange,提问作者Adamszsz
相关产品推荐
相关产品推荐

