ResGen.exe在重定向输出时卡住了

3
我尝试重定向来自ResGen.exe的标准输出。我使用以下代码:

我尝试从ResGen.exe重定向标准输出。我使用以下代码:

ProcessStartInfo psi = new ProcessStartInfo( "resxGen.exe" );
psi.CreateNoWindow = true;
psi.Arguments = sb.ToString();
psi.UseShellExecute = false;
psi.RedirectStandardOutput = true;
Process p = Process.Start( psi );
p.WaitForExit();
StreamReader sr = p.StandardOutput;
string message = p.StandardOutput.ReadToEnd();

它卡在了p.WaitForExit上。当我关闭输出流重定向并且不读取StandardOutput时,它可以正常工作。

我做错了什么?

2个回答

5
在读取流后,您需要等待进程结束,否则代码会出现死锁。问题在于您的父进程正在阻塞等待子进程完成,而子进程正在等待父进程读取输出,因此会发生死锁。 这里提供了一个很好且详细的问题描述。
像这样更改您的代码应该可以避免死锁:
StreamReader sr = p.StandardOutput;
string message = p.StandardOutput.ReadToEnd();
p.WaitForExit();

1
是的。读取输出,而不是“写入输出”。输出缓冲区很小,典型值为2千字节。在WaitForExit之前进行ReadToEnd就足够了,“结束”直到程序结束才会发生。 - Hans Passant
谢谢。然而,如果您需要实时将应用程序的输出写入UI,那么问题会变得更加复杂,这种方法无法解决。 - Can Gencer

1

最重要的是,p.WaitForExit的位置似乎不正确;应该在从流中读取所需内容后才调用此方法。

来自MSDN

 // Start the child process.
 Process p = new Process();
 // Redirect the output stream of the child process.
 p.StartInfo.UseShellExecute = false;
 p.StartInfo.RedirectStandardOutput = true;
 p.StartInfo.FileName = "Write500Lines.exe";
 p.Start();
 // Do not wait for the child process to exit before
 // reading to the end of its redirected stream.
 // p.WaitForExit();
 // Read the output stream first and then wait.
 string output = p.StandardOutput.ReadToEnd();
 p.WaitForExit();

还要注意,你在这里使用StreamReader sr = p.StandardOutput是多余的,因为当message的值被设置时,你可以使用p.StandardOutput.ReadToEnd();来访问流 - 注意p.StandardOutputsr.ReadToEnd()的区别。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接