ProcessStartInfo挂在“WaitForExit”上?为什么?

ProcessStartInfo挂在“WaitForExit”上?为什么?

我有以下代码:

info = new System.Diagnostics.ProcessStartInfo("TheProgram.exe", String.Join(" ", args));
info.CreateNoWindow = true;info.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
info.RedirectStandardOutput = true;info.UseShellExecute = false;System.Diagnostics.Process p = System.Diagnostics.Process.Start(info);
p.WaitForExit();Console.WriteLine(p.StandardOutput.ReadToEnd()); //need the StandardOutput contents

我知道从我开始的过程中输出的长度大约是7MB。在Windows控制台中运行它可以正常工作。不幸的是,从编程的角度来看,这将无限期挂在WaitForExit注意,这做了代码,而不是挂起较小的输出(如3kb)。

是否可能ProcessStartInfo中的内部StandardOutput无法缓冲7MB?如果是的话,我应该做些什么呢?如果没有,我做错了什么?


鸿蒙传说
浏览 1100回答 3
3回答

HUH函数

问题是如果你重定向StandardOutput和/或StandardError内部缓冲区可能会满。不管你用什么命令,都会有问题:如果在读取之前等待进程退出StandardOutput进程可以阻止试图写入它,因此进程永远不会结束。如果你读到StandardOutput然后使用ReadToEnd你的如果进程从未关闭,则进程可以阻塞。StandardOutput(例如,如果它从未终止,或者如果它被阻止,则写入StandardError).解决方案是使用异步读取来确保缓冲区没有满。以避免任何死锁,并收集两者的所有输出。StandardOutput和StandardError你可以这样做:编辑:有关如何避免ObjectDisposedException如果发生超时。using (Process process = new Process()){     process.StartInfo.FileName = filename;     process.StartInfo.Arguments = arguments;     process.StartInfo.UseShellExecute = false;     process.StartInfo.RedirectStandardOutput = true;     process.StartInfo.RedirectStandardError = true;     StringBuilder output = new StringBuilder();     StringBuilder error = new StringBuilder();     using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false))     using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false))     {         process.OutputDataReceived += (sender, e) => {             if (e.Data == null)             {                 outputWaitHandle.Set();             }             else             {                 output.AppendLine(e.Data);             }         };         process.ErrorDataReceived += (sender, e) =>         {             if (e.Data == null)             {                 errorWaitHandle.Set();             }             else             {                 error.AppendLine(e.Data);             }         };         process.Start();         process.BeginOutputReadLine();         process.BeginErrorReadLine();         if (process.WaitForExit(timeout) &&             outputWaitHandle.WaitOne(timeout) &&             errorWaitHandle.WaitOne(timeout))         {             // Process completed. Check process.ExitCode here.         }         else         {             // Timed out.         }     }}

牛魔王的故事

我只想添加以下内容:在释放outputWaitHandle和ErrorWaitHandle之前,需要移除OutputDataReciser和ErrorDataReces委托。如果进程在超时之后继续输出数据,然后终止,则在释放后将访问outputWaitHandle和errorWaitHandle变量。
打开App,查看更多内容
随时随地看视频慕课网APP