Visual Studio调试 - System.Diagnostics.Process在WaitForExit上挂起

时间:2016-05-17 13:21:44

标签: c# process visual-studio-2015 windows-10 waitforexit

在控制台应用程序,Windows 10,Visual Studio 2015,.NET 4.6中,我在Main中调用名为TestProcess的单个方法。构建模式调试,如果我在没有调试的情况下运行app,它会打印正确的文本:

  

827ccb0eea8a706c4c34a16891f84e7b * test.txt

     

按任意键继续   。 。

如果我使用调试运行应用程序,则在打印前等待3秒

  

错误False False False''''

这只是对实际问题的简化,这段代码是一些复杂代码的主干,它在没有调试md5sums.exe的情况下也会在发行版中挂起,但适用于其他一些程序。 Coplex代码也会挂起 var a = proc.WaitForExit(timeout); ,直到超时,如附加示例所示。另一方面,这种简化将在没有调试器的情况下发布。所有这些问题始于Windows 10,在Windows 7上它都运行良好。

[编辑]无法理解为什么md5sums.exe会导致问题,如果我使用别的东西,即。 FileName =“ping”,Arguments =“localhost”一切都按预期工作。

[EDIT2]我的复杂程序停止在Windows 10上运行(发布 - 无需调试运行),但此示例也在Windows 7上挂起(调试 - 运行调试)

        static void TestProcess()
        {
            using (var proc = new Process())
            {
                proc.StartInfo.FileName = "md5sums.exe";
                proc.StartInfo.WorkingDirectory = @"C:\Temp\ProcessDebug";
                proc.StartInfo.Arguments = "-u test.txt";
                proc.StartInfo.CreateNoWindow = true;
                proc.StartInfo.UseShellExecute = false;
                proc.StartInfo.RedirectStandardOutput = true;
                proc.StartInfo.RedirectStandardError = true;
                StringBuilder output = new StringBuilder();
                StringBuilder error = new StringBuilder();
                using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false))
                using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false))
                {
                    proc.OutputDataReceived += (sender, e) =>
                    {
                        if (e.Data == null)
                            outputWaitHandle.Set();
                        else
                            output.AppendLine(e.Data);
                    };
                    proc.ErrorDataReceived += (sender, e) =>
                    {
                        if (e.Data == null)
                            errorWaitHandle.Set();
                        else
                            error.AppendLine(e.Data);
                    };
                    proc.Start();
                    proc.BeginOutputReadLine();
                    proc.BeginErrorReadLine();
                    var timeout = 1000;
                    var a = proc.WaitForExit(timeout);
                    var b = outputWaitHandle.WaitOne(timeout);
                    var c = errorWaitHandle.WaitOne(timeout);
                    if (a && b && c)
                        Console.WriteLine(output.ToString());
                    else
                        Console.WriteLine($"Error {a} {b} {c} '{output}' '{error}'");
                }
            }
        }

1 个答案:

答案 0 :(得分:1)

有3个渔获量可以解决这个问题:

  • md5sums.exe在某些情况下在使用我的设置启动后暂停执行:
  

827ccb0eea8a706c4c34a16891f84e7b * test.txt

     

按ENTER退出

如果CreateNoWindow设置为false并且stdout,stderr重定向被删除,则可以观察到这种情况。这可以通过使用-e开关来解决: '立即退出;在返回' 之前不要暂停。这将解决所有情况。但由于我没有使用-e,我的行为会有不一致,具体取决于调试器和Windows版本。

  • 当没有调试运行时,虽然所有设置都相同,但没有触发暂停,并且“按ENTER退出”不在输出中。但运行调试导致暂停,阻止程序直到超时,其中md5sums将挂起在任务管理器中等待Enter。
  • 在发布模式下,在没有调试的情况下运行,虽然暂停触发并且“按ENTER退出”在Windows 7上输出md5sums返回并继续执行而没有阻塞并且达到超时。在Windows 10上不是这种情况,md5sums将在任务管理器中等待Enter并且在达到超时后继续执行程序。