pConsole.StartInfo.RedirectStandardOutput和pConsole.Exit事件(c#)
我有一个GUI应用程序,它执行(在新流程中)“控制台”应用程序并解析输出。要重定向输出,我将pConsole.StartInfo.RedirectStandardOutput设置为true。我还订阅了事件pConsole.Exited 我看到的问题是,我必须在退出的事件处理程序中使用Thread.Sleep()来获取最后的数据 我退出的事件处理程序如下所示:pConsole.StartInfo.RedirectStandardOutput和pConsole.Exit事件(c#),c#,console,process,C#,Console,Process,我有一个GUI应用程序,它执行(在新流程中)“控制台”应用程序并解析输出。要重定向输出,我将pConsole.StartInfo.RedirectStandardOutput设置为true。我还订阅了事件pConsole.Exited 我看到的问题是,我必须在退出的事件处理程序中使用Thread.Sleep()来获取最后的数据 我退出的事件处理程序如下所示: Thread.Sleep(100); // Wait for additional data (if any). pConsole.Out
Thread.Sleep(100); // Wait for additional data (if any).
pConsole.OutputDataReceived -= new System.Diagnostics.DataReceivedEventHandler(this.localTerminal_DataAvailableEvent);
int exit = pConsole.ExitCode;
pConsole.Dispose();
pConsole = null;
似乎退出的事件在我的最后一个pConsole_DataAvailableEvent之前执行。有人知道这是怎么发生的吗
我还使用互斥锁/锁来确保在开始执行下一个控制台应用程序之前退出的事件已完成。我强烈怀疑这只是操作系统刷新任何输出缓冲区。看起来你的解决方法还行,虽然很明显这很难看(不是你的错),而且在某些情况下睡眠时间可能会浪费太长,而在某些情况下睡眠时间可能不够长。我不知道这是否更好,但我只是在看一些类似的东西,使用线程来阅读stderr/stdout,如下所示。它涉及一些额外的线程(以避免死锁/复杂的异步代码),但似乎工作得非常稳定 这里的关键是我在处理IO的两个线程上执行了Join(),因此我只在两个输出流都被完全消耗之后才继续
using (Process proc = Process.Start(psi))
{
Thread stdErr = new Thread(DumpStream(proc.StandardError, Console.Error));
Thread stdOut = new Thread(DumpStream(proc.StandardOutput, Console.Out));
stdErr.Name = "stderr reader";
stdOut.Name = "stdout reader";
stdErr.Start();
stdOut.Start();
proc.WaitForExit();
stdOut.Join();
stdErr.Join();
if (proc.ExitCode != 0) {...} // etc
}
static ThreadStart DumpStream(TextReader reader, TextWriter writer)
{
return (ThreadStart) delegate
{
string line;
while ((line = reader.ReadLine()) != null) writer.WriteLine(line);
};
}
问题几乎肯定是输出缓冲:进程退出,触发退出事件,但一些输出数据仍在缓冲区中。您的黑客可能在某些情况下有效,但其他方法可能更健壮。考虑: 1) 消除退出的事件处理程序,改为检查OutputDataReceived处理程序中的Process.HasExit
2) 不要使用OutputDataReceived处理程序,只需在Process.StandardOutput流上调用Read()。一旦流关闭,进行后处理清理。除了Marc Gravell的答案之外 proc.StandardError和proc.StandardOutput都有EndOfStream方法。
这将有助于确定在用户输入/提示之前输出不产生换行符的情况此解决方案也适用于.NET 1.1。我们中的一些人仍然需要维护遗留代码。