读取其他进程控制台输出

我在“wave”中返回控制台输出时遇到问题。 例如,控制台每秒输出一些东西,例如事件每分钟触发60次(同时所有事件)。

我的代码:

Process Proc = new Process(); Proc.StartInfo.FileName = SSMS.BinaryDir + "HldsUpdateTool.exe"; Proc.StartInfo.Arguments = "-command update -game tf -dir " + SSMS.RootDir + Key; Proc.StartInfo.UseShellExecute = false; Proc.StartInfo.RedirectStandardOutput = true; Proc.StartInfo.RedirectStandardError = true; Proc.EnableRaisingEvents = true; Proc.StartInfo.CreateNoWindow = false; Proc.ErrorDataReceived += new DataReceivedEventHandler(Proc_ErrorDataReceived); Proc.OutputDataReceived += new DataReceivedEventHandler(Proc_OutputDataReceived); Proc.Exited += new EventHandler(Proc_Exited); Proc.Start(); Proc.BeginErrorReadLine(); Proc.BeginOutputReadLine(); 

我可能怀疑更新工具有问题。 其他带控制台输出的程序运行正常。

触发事件时的时间线:( =什么都没发生; |事件被触发)

 Should be: ==|==|==|==|==|==|== Is: ========|||||||=========||||||===== 

您正在看到程序正在使用的stdout输出缓冲区的效果。 这是C运行时库的标准function,当检测到缓冲区正在写入管道而不是控制台时,会启用缓冲。 而不是在程序中的每个printf()语句之后自动刷新。 缓冲区通常约为2千字节。 只有当它填满时才会被冲洗。 这大大提高了效率,每次刷新都会增加很多开销。 在正常重定向方案中,将输出写入文件或设备时很重要。

你可以看到它的发展方向,你看到的那块是该缓冲区的内容。 没有简单的解决办法,程序中需要手术来禁用缓冲区或在重要的地方冲洗它。 这总是在降压停止的地方,如果你可以改变程序你就不会这样做。 您可以通过缓冲从OutputDataReceived获得的内容来滴灌您的控制台,但这可能有点愚蠢。

当程序发送输出的速度超过处理速度时,您将看不到此效果。 这很常见。 它有效地被限制,阻塞,同时等待输出缓冲区清空并快速填充它。

还有一个解释,OutputReceived可以触发的速率还取决于你运行的线程池线程数。 如果这超过了cpu核心的数量,则调用OutputReceived的tp线程可能会延迟0.5秒的倍数。 但是,您会看到重定向的所有程序的聚集。

我对C#并不熟悉,但您可以通过搜索控制台刷新的文档找到有关此问题的有用信息。

也许是这样的:

 Console.Out.Flush() 

如果您正在打印到错误流,请考虑使用Console.Out.Flush() (和Console.Error.Flush() )。

据我了解,处理程序没有使用Console.Out.Write()写入命令行 – 它们正在写入一个缓冲区,其他句柄会打印出来。 通过多次调用Console.Out.Write() ,所有的bufferes不会立即写入 – 有些文本留在缓冲区中的时间比其他文本长。 Console.Out.Flush()强制系统立即写入其当前缓冲区。