读取其他进程控制台输出

Sem*_*mas 6 c# console process

我在"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();
Run Code Online (Sandbox Code Playgroud)

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

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

Should be: ==|==|==|==|==|==|==  
Is: ========|||||||=========||||||=====
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 6

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

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

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

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