异步读取进程输出时的延迟
我正在使用 .NET 和 C# 启动一个进程并异步读取它的输出。我的问题是,在我的程序读取输出之前似乎存在延迟。如果我在命令行上运行可执行文件,则在它开始运行时立即有输出。但是,当我使用代码运行它时,在进程退出之前不会调用 ReadOutput 事件处理程序。我想用它来提供进程输出的实时视图,所以我不想等待(几分钟)直到进程退出。
这是一些相关代码:
MyProcess = new Process();
MyProcess.StartInfo.FileName = command;
MyProcess.StartInfo.Arguments = args;
MyProcess.StartInfo.UseShellExecute = false;
MyProcess.StartInfo.RedirectStandardOutput = true;
MyProcess.StartInfo.RedirectStandardError = true;
MyProcess.StartInfo.RedirectStandardInput = true;
MyProcess.OutputDataReceived += new DataReceivedEventHandler(ReadOutput);
MyProcess.ErrorDataReceived += new DataReceivedEventHandler(ReadOutput);
if (!MyProcess.Start())
{
throw new Exception("Process could not be started");
}
try
{
MyProcess.BeginOutputReadLine();
MyProcess.BeginErrorReadLine();
}
catch (Exception ex)
{
throw new Exception("Unable to begin asynchronous reading from process";
}
这是我的事件处理程序:
private void ReadOutput(object sendingProcess, DataReceivedEventArgs outLine)
{
OutputBuilder.AppendLine(outLine.Data);
Console.WriteLine(outLine.Data);
Console.Out.Flush();
}
I am using .NET and C# to start a process and read it's output asynchronously. My problem is that there seems to be a delay before the output is read by my program. If I run the executable on the command line, there is output immediately when it starts running. But when I run it using my code the ReadOutput event handler isn't called until the Process exits. I want to use this to provide a real-time view of the process's output, so I don't want to wait (several minutes) until the process exits.
Here's some relevant code:
MyProcess = new Process();
MyProcess.StartInfo.FileName = command;
MyProcess.StartInfo.Arguments = args;
MyProcess.StartInfo.UseShellExecute = false;
MyProcess.StartInfo.RedirectStandardOutput = true;
MyProcess.StartInfo.RedirectStandardError = true;
MyProcess.StartInfo.RedirectStandardInput = true;
MyProcess.OutputDataReceived += new DataReceivedEventHandler(ReadOutput);
MyProcess.ErrorDataReceived += new DataReceivedEventHandler(ReadOutput);
if (!MyProcess.Start())
{
throw new Exception("Process could not be started");
}
try
{
MyProcess.BeginOutputReadLine();
MyProcess.BeginErrorReadLine();
}
catch (Exception ex)
{
throw new Exception("Unable to begin asynchronous reading from process";
}
And here's my event handler:
private void ReadOutput(object sendingProcess, DataReceivedEventArgs outLine)
{
OutputBuilder.AppendLine(outLine.Data);
Console.WriteLine(outLine.Data);
Console.Out.Flush();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是我根据我的评论使用 lambda 语法执行此操作的方式 (C# 3)。
This is the way I do it (C# 3) as per my comment using the lambda syntax.
您的方法中的问题可能是该进程仅在退出时完成一行的输出。无法控制异步事件处理程序何时触发。
在控制台应用程序中,最好的选择是定期检查新输出并同步读取和显示它:
在 UI 项目中,您可以使用 WinForms 的
Timer
或DispatcherTimer
和 WPF 分别调用循环内容并更新 UI。请注意,我不会刷新
Console.Out
,因为Console.Write()
和Console.WriteLine()
会自动导致此情况。The problem in your approach is probably that the process only finishes the output of a line when it exits. There's no way to control when the asynchronous event handlers fire.
In a console application, your best bet is to periodically check for new output and read and display it synchronously:
In a UI project, you'd use
Timer
orDispatcherTimer
for WinForms and WPF, respectively, to call the contents of the loop and update the UI.Note that I don't flush
Console.Out
, asConsole.Write()
andConsole.WriteLine()
cause this automatically.尝试添加
MyProcess.WaitForExit
方法调用:Try to add
MyProcess.WaitForExit
method call: