通过 Process.Start(startInfo) 对另一个进程的奇怪行为 - 继续 [英] strange behaviour on another process via Process.Start(startInfo) -- continue

查看:24
本文介绍了通过 Process.Start(startInfo) 对另一个进程的奇怪行为 - 继续的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

原始位置(通过 Process.Start 在另一个进程上的奇怪行为(startInfo)) 不允许我正确发布测试代码.我必须在这里开始一个新问题.

The original location (strange behaviour on another process via Process.Start(startInfo)) doesn't allow me post test code properly. I have to start a new question here.

我们的 C#(V3.5) 需要调用 C++ 可执行文件来处理原始数据文件并为我们生成结果文件.

Our C#(V3.5) needs to call a C++ executable to process a raw data file and generate result files for us.

它以前使用以下代码工作(没有 ReadToEnd() 或 ReadLine() 调用):

It worked before with the following code (without ReadToEnd() or ReadLine() call):

startInfo.UseShellExecute = false;
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardOutput = true;

现在输入的原始数据文件发生了变化(比以前更大).我们对该可执行文件的调用将永远挂起.根据建议,我添加了 ReadToEnd() 或 ReadLine() 但它会挂在这些调用上.所以我必须使用 startInfo.UseShellExecute = true; 或 set

Now the input raw data file changed (bigger than before). Our call to that executable will hang forever. Based on advice, I added ReadToEnd() or ReadLine() but it will hang on those calls. So I have to either use startInfo.UseShellExecute = true; or set

startInfo.UseShellExecute = false; 
// and with
startInfo.RedirectStandardError = false;
startInfo.RedirectStandardOutput = false;

不知道为什么?

以下是我测试过的案例:

Following are cases I tested:

  1. 工作案例:

  1. working case:

ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardError = false;
startInfo.RedirectStandardOutput = false;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = path;
startInfo.Arguments = rawDataFileName;
//startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1);
try
{
    Process correctionProcess = Process.Start(startInfo);
    correctionProcess.WaitForExit();
}

  • 工作案例:

  • working case:

    ProcessStartInfo startInfo = new ProcessStartInfo();
    startInfo.CreateNoWindow = true;
    startInfo.UseShellExecute = true;
    startInfo.RedirectStandardError = false;//can be commented out
    startInfo.RedirectStandardOutput = false;//can be commented out
    startInfo.WindowStyle = ProcessWindowStyle.Hidden;
    startInfo.FileName = path;
    startInfo.Arguments = rawDataFileName;
    startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1);
    try
    {
        Process correctionProcess = Process.Start(startInfo);
        correctionProcess.WaitForExit();
    }
    

  • 不工作的情况(使用ReadLine()):

    ProcessStartInfo startInfo = new ProcessStartInfo();
    startInfo.CreateNoWindow = true;
    startInfo.UseShellExecute = false;
    startInfo.RedirectStandardError = true;
    startInfo.RedirectStandardOutput = true;
    startInfo.WindowStyle = ProcessWindowStyle.Hidden;
    startInfo.FileName = path;
    startInfo.Arguments = rawDataFileName;
    //startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1);
    try
    {
        Process correctionProcess = Process.Start(startInfo);
        while (!correctionProcess.HasExited)
        {
            Log.logItem(LogType.Performance, "read errorMsg @@@@", "DPTM::correctData()", "");
            string errorMsg = correctionProcess.StandardError.ReadLine(); // <-- Hangs here
            Log.logItem(LogType.Performance, "read errorMsg", "DPTM::correctData()", "errorMsg=" + errorMsg);
            string outputMsg = correctionProcess.StandardOutput.ReadLine();
            Log.logItem(LogType.Performance, "read outputMsg", "DPTM::correctData()", "outputMsg=" + outputMsg);
            Thread.Sleep(100);
        }
    }
    

  • 不工作的情况(使用ReadToEnd()):

    ProcessStartInfo startInfo = new ProcessStartInfo();
    startInfo.CreateNoWindow = true;
    startInfo.UseShellExecute = false;
    startInfo.RedirectStandardError = true;
    startInfo.RedirectStandardOutput = true;
    startInfo.WindowStyle = ProcessWindowStyle.Hidden;
    startInfo.FileName = path;
    startInfo.Arguments = rawDataFileName;
    //startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1);
    try
    {
        Process correctionProcess = Process.Start(startInfo);
        while (!correctionProcess.HasExited)
        {
            Log.logItem(LogType.Performance, "read errorMsg @@@@", "DPTM::correctData()", "");
            string errorMsg = correctionProcess.StandardError.ReadToEnd(); // <-- Hangs here!
            Log.logItem(LogType.Performance, "read errorMsg", "DPTM::correctData()", "errorMsg=" + errorMsg);
            string outputMsg = correctionProcess.StandardOutput.ReadToEnd();
            Log.logItem(LogType.Performance, "read outputMsg", "DPTM::correctData()", "outputMsg=" + outputMsg);
            Thread.Sleep(100);
        }
    }
    

  • 不工作的情况:

  • NOT working case:

    ProcessStartInfo startInfo = new ProcessStartInfo();
    startInfo.CreateNoWindow = true;
    startInfo.UseShellExecute = false;
    startInfo.RedirectStandardError = true;
    startInfo.RedirectStandardOutput = true;
    startInfo.WindowStyle = ProcessWindowStyle.Hidden;
    startInfo.FileName = path;
    startInfo.Arguments = rawDataFileName;
    //startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1);
    try
    {
        Process correctionProcess = Process.Start(startInfo);
        Log.logItem(LogType.Performance, "read errorMsg @@@@", "DPTM::correctData()", "");
        string errorMsg = correctionProcess.StandardError.ReadToEnd(); // <-- Hangs here!
        Log.logItem(LogType.Performance, "read errorMsg", "DPTM::correctData()", "errorMsg=" + errorMsg);
        string outputMsg = correctionProcess.StandardOutput.ReadToEnd();
        Log.logItem(LogType.Performance, "read outputMsg", "DPTM::correctData()", "outputMsg=" + outputMsg);
        correctionProcess.WaitForExit();
    }
    

  • 推荐答案

    您在错误/输出缓冲区上陷入僵局.您的第二个进程正在等待缓冲区释放,而您正在等待该进程完成.您需要异步读取输出/错误流以防止这种情况发生.

    you are deadlocked on the error/output buffer. Your second process is waiting for the buffer to free up while you are waiting for that process to finish. You need to asynchronously read output/error streams to prevent that.

    查看您的 MSDN 示例:哇,那个示例真是令人困惑……如果他们只是将其限制为 std 输出或 std 错误,会更容易理解.

    Looking at your MSDN sample: wow that sample is really confusing... It would've been easier to follow if they just limited it to std out or std error.

    您需要先设置数据处理程序

    You need to first set data handler

    correctionProcess.OutputDataReceived += new DataReceivedEventHandler(OutputDataHandler);
    

    然后调用

    p.BeginOutputReadLine();
    

    就像评论 [令人困惑地] 建议不要尝试读取那里的输出.改用处理程序.

    Just like comment [confusingly] advises do no try to read output there. Use handler instead.

        private void OutputDataHandler(object sendingProcess, DataReceivedEventArgs data)
        {
            if (data.Data != null)
            {
                // append data.Data to your internal buffer (StringBuilder?)
            }
        }
    

    这篇关于通过 Process.Start(startInfo) 对另一个进程的奇怪行为 - 继续的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆