zoukankan      html  css  js  c++  java
  • C# 启动 Python 不能及时获取输出信息

    问题描述:项目需要调用python的一套程序去处理一些问题,然后我用Process 类启动一个进程,调用了python程序,通过实时输出获取执行进度信息,但是执行的时候我发现输出并不是实时的。

    1、调用外部程序的代码是这样的

            public static Process CommitCommand(string commandStr, string workingDir, Action<DataReceivedEventArgs> action)
            {
                var logger = LogManager.GetCurrentClassLogger();
                try
                {
                    logger.Debug("Get into CommitCommand");
                    Process process = new Process();
                    process.StartInfo.FileName = commandStr.Substring(0, commandStr.IndexOf(" ")).Trim();
                    var pathDir = Environment.GetEnvironmentVariable("PATH").Split(RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? ":" : ";", StringSplitOptions.RemoveEmptyEntries)
                        .FirstOrDefault(s =>
                            File.Exists(Path.Combine(s, process.StartInfo.FileName)) ||
                            File.Exists(Path.Combine(s, process.StartInfo.FileName + ".exe")));
                    if (string.IsNullOrEmpty(pathDir))
                    {
                        process.StartInfo.FileName = Path.GetFullPath(process.StartInfo.FileName, workingDir);
                    }
                    process.StartInfo.Arguments = commandStr.Substring(commandStr.IndexOf(" ")).Trim();
                    process.StartInfo.WorkingDirectory = string.IsNullOrWhiteSpace(workingDir) ? process.StartInfo.WorkingDirectory : workingDir;
                    process.StartInfo.CreateNoWindow = true;
                    process.StartInfo.ErrorDialog = false;
                    process.StartInfo.UseShellExecute = false;
                    process.StartInfo.RedirectStandardOutput = true;
                    process.StartInfo.RedirectStandardError = true;
                    process.StartInfo.RedirectStandardInput = true;
                    process.ErrorDataReceived += (sender, args) =>
                    {
                        action(args);
                        logger.Error($"ErrorDataReceived:commandStr:{commandStr}. workingDir:{workingDir}. Error:{args.Data}");
                    };
                    process.EnableRaisingEvents = true;
                    process.OutputDataReceived += (sender, args) =>
                    {
                        action(args);
                        logger.Debug($"OutputDataReceived:{args.Data}");
                    };
                    process.Exited += (sender, args) =>
                    {
                        logger.Debug("程序退出!");
                        logger.Error($"Exited:commandStr:{commandStr}. workingDir:{workingDir}");
                    };
                    process.Start();
    
                    process.StandardInput.AutoFlush = true;
                    process.BeginErrorReadLine();
                    process.BeginOutputReadLine();
                    logger.Debug("Sign out CommitCommand");
                    return process;
                }
                catch (Exception e)
                {
                    logger.Error(e, "process can not start.");
                    logger.Debug(e.Message);
                    return null;
                }
            }

    2、问题分析

           正常情况下,每次输出都会触发OutputDataReceived事件,但是实际上的输出是在执行完成之后一次性输出的,网上搜索后发现只有 C#编写的程序才能直接正常运行,其他语言编写的程序都会遇到这个问题。而解决办法的思路都是一样的,在不同语言中调用打印方法后,接着调用一个类似 flush 的方法,比如在 python中就是 sys.stdout.flush()方法,这样就能每次 print之后触发 OutputDataReceived 事件了。

    3、解决办法

         然后我在python的输出代码下,加了sys.stdout.flush()之后,可以时候获取输出信息了。

  • 相关阅读:
    咱家自己的vim配置
    Oauth2手册 第一章
    tcpdf 将网页生成pdf
    Lua 学习记事本
    Lua中的table函数(转)
    Lua常用函数
    将显示对象变成黑白
    Flash 3D 基础
    高等物理:数值积分
    Camera类的基本使用
  • 原文地址:https://www.cnblogs.com/zhangjd/p/12794582.html
Copyright © 2011-2022 走看看