2011-09-07 13 views
2

考慮這個例子的C#代碼(無關件離開了):異步使用System.Diagnostics.Process,我應該如何確保在確定退出之前收到最後一個輸出?

using System.Diagnostics.Process; 

var process = new Process(); 
var startInfo = process.StartInfo; 
startInfo.RedirectStandardOutput = true; 
startInfo.RedirectStandardError = true; 
process.EnableRaisingEvents = true; 
process.OutputDataReceived += OutputHandler; 
process.ErrorDataReceived += ErrorHandler; 
process.Exited += ExitHandler; 
process.Start(); 
process.BeginOutputReadLine(); 
process.BeginErrorReadLine(); 

現在,我要通知偵聽器的過程結束後,沒有更多的輸出(stdout /標準錯誤),以從中讀取。如何確保在我的ExitHandler方法中,在確定進程已真正完成之前,所有剩餘的stdout/stderr都由OutputHandlerErrorHandler處理?

回答

3

當您顯式使用Process.WaitForExit(-1)時存在聯鎖。直到stdout和stderr的異步讀取器顯示文件結束狀態後纔會返回。在您的Exited事件處理程序中調用它。您必須使用-1的超時時間,否則這將不起作用。或者只是WaitForExit()。這很好,你知道它已經退出。

+0

所以這是一個已知的模式,用於確保stdout/stderr處理在'Exited'處理程序中完成? – aknuds1

+0

我看到'WaitForExit()'文檔說:*這個方法指示Process組件等待無限的時間讓進程和事件處理程序退出。*這實際上聽起來像我需要的。在所有其他事件處理完成後,我認爲'Exited'處理程序中沒有任何保證。 – aknuds1

+0

我將其標記爲解決方案,因爲從參考文檔看來它是正確的。我認爲負面超時是不必要的,但根據參考,它應該對應於'WaitForExit()'過載。 – aknuds1

0

當進程中止或終止時調用Exited事件。因此,永遠不會有數據需要閱讀的情況。

當操作系統關閉進程時,會通知正在等待退出的任何進程組件 。然後,組件可以通過使用 句柄訪問 操作系統內存中仍駐留在 內存中的關聯進程信息(例如ExitTime屬性)。

由於關聯進程已退出,因此 組件的Handle屬性不再指向現有的進程資源。 只能用於訪問操作系統有關 過程資源的信息。系統知道處理還沒有被進程組件釋放的進程 ,所以它 將ExitTime和Handle屬性信息保留在內存中,直到 進程組件專門釋放資源。

+0

我應該在我的ExitHandler方法中調用'WaitForExit'? – aknuds1

+0

對不起小姐瞭解的問題,更新。 – TheCodeKing

+0

嗯......我以爲我經歷過一次'OutputHandler'在調用'ExitHandler'之後在另一個線程中調用了非空數據。也許這是爲了另一個進程(我開始了兩個進程),我不太確定了...... – aknuds1

相關問題