2011-03-19 86 views
6

我有問題,當在「波浪」返回控制檯輸出。例如,控制檯每秒都會輸出一些內容,例如事件每分鐘觸發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: ========|||||||=========||||||===== 
+0

我認爲你必須刷新輸出。不知道怎麼回事 – BlackBear 2011-03-19 12:50:58

回答

6

您看到該程序使用標準輸出輸出緩衝的效果。這是C運行時庫的標準功能,當檢測到它正在寫入管道而不是控制檯時啓用緩衝。而不是在程序中的每個printf()語句後自動刷新。緩衝區通常在2千字節左右。只有當它填滿時纔會被刷新。這大大提高了效率,每次刷新都會增加很多開銷。重要的是在正常重定向的情況下,當輸出寫入文件或設備時。

你可以看到這是怎麼回事,你看到的團塊緩衝區的內容。對此沒有簡單的解決方法,程序中需要進行手術以禁用緩衝區或將其清空。如果你能改變這個計劃,那麼總是在那個地方停下來,你不會這麼做。你可以通過緩衝你從OutputDataReceived得到的內容來控制你的控制檯,但這可能有點愚蠢。

當程序發送輸出速度比你可以處理它,你不會看到這種效果。這很常見。它在等待輸出緩衝區清空並快速填充備份時被有效地限制,阻塞。

有這一個更多的解釋,速率OutputReceived也開火取決於你有多少個線程池線程上運行。如果超過了cpu內核的數量,調用OutputReceived的tp線程可能會延遲0.5秒的倍數。然而,你會看到你重新定向的所有程序上的聚集。

+0

可能也想看看這個: http://alabaxblog.info/2013/06/redirectstandardoutput-beginoutputreadline-pattern-broken/ – Almund 2015-09-15 13:49:15

0

我絕不熟悉C#,但你可能會被搜索的文檔中找到有關這個問題的有用信息爲控制檯沖洗

也許是這樣的:

Console.Out.Flush() 
0

考慮使用Console.Out.Flush()(和Console.Error.Flush(),如果你打印到錯誤流爲好)。

據我所知,處理程序沒有寫入命令行Console.Out.Write() - 他們正在寫入緩衝區,其他處理的內容會打印出來。通過多次調用Console.Out.Write(),所有的bufferes不會一次寫入 - 有些文本會比其他文本保留更長的時間。 Console.Out.Flush()強制系統立即寫入其當前緩衝區。