[英]System.Diagnostics.Process.Start weird behaviour
我正在編寫一個應用程序來啟動和監視C#中的其他應用程序。 我正在使用System.Diagnostics.Process類來啟動應用程序,然后使用Process.Responding屬性監視應用程序,以每100毫秒輪詢一次應用程序的狀態。 我使用Process.CloseMainWindow來停止應用程序或Process.Kill如果它沒有響應就殺死它。
我注意到一種奇怪的行為,有時進程對象進入一種狀態,即當底層進程在循環中掛起並且它不響應CloseMainWindow時,響應屬性總是返回true。
重現它的一種方法是在啟動流程實例后立即輪詢Responding屬性。 所以舉個例子
_process.Start();
bool responding = _process.Responding;
將重現錯誤狀態
_process.Start();
Thread.Sleep(1000);
bool responding = _process.Responding;
將工作。 將睡眠周期減少到500將再次引入錯誤狀態。
啟動后調用_process.Responding太快的東西似乎阻止了對象獲取正確的Windows消息隊列處理程序。 我想我需要等待_process.Start完成它的異步工作。 有沒有比調用Thread.Sleep更好的方法來等待這個? 我不太自信1000毫秒總是足夠的。
現在,我需要稍后檢查一下,但我確信有一個方法告訴線程等待它准備輸入。 您是否僅監控GUI流程?
是不是Process.WaitForInputIdle對你有任何幫助? 或者我錯過了這一點? :)
在Twitter(或推文推文?)與門德爾聊天之后,我想我應該更新我的答案,以便社區充分了解...
WaitForInputIdle
僅適用於具有GUI的應用程序。 希望有幫助:)
我認為增強對_process.Responding的檢查可能會更好,這樣如果Responding屬性返回false超過5秒(例如),你只會嘗試停止/終止進程。
我想你可能會發現,在他們進行更密集的處理時,應用程序可能會在一瞬間“沒有響應”。
我相信一種更寬松的方法會更好地工作,允許一個過程在短時間內“沒有響應”,只有在幾秒鍾內(或者你想要多長時間)反復“沒有響應”時才采取行動。
進一步說明:Microsoft文檔表明Responding屬性與用戶界面特別相關,這就是新啟動的進程可能沒有立即響應UI的原因。
謝謝你的回答。 這個
_process.Start();
_process.WaitForInputIdle();
似乎解決了這個問題。 它仍然很奇怪,因為Responding和WaitForInputIdle都應該使用相同的win32 api調用。
更多背景信息
GUI應用程序有一個帶有消息隊列的主窗口。 Responding和WaitForInputIdle通過檢查進程是否仍處理來自此消息隊列的消息來工作。 這就是他們只使用GUI應用程序的原因。 不知怎的,似乎調用Responding太快會干擾讓Process獲取該消息隊列的句柄。 調用WaitForInputIdle似乎解決了這個問題。
我將不得不潛入反射器,看看我是否能理解這一點。
更新
似乎在啟動后檢索與進程關聯的窗口句柄足以觸發奇怪的行為。 像這樣:
_process.Start();
IntPtr mainWindow = _process.MainWindowHandle;
我使用Reflector進行了檢查,這就是Responding在幕后所做的事情。 似乎如果你太快得到MainWindowHandle,你會得到錯誤的一個,並且它會在進程的剩余生命周期中使用這個錯誤的句柄,或者直到你調用Refresh();
更新
調用WaitForInputIdle()只能在某些時候解決問題。 每次讀取Responding屬性時調用Refresh()似乎都會更好。
我在大約兩年前的一個項目中也注意到了這一點。 在請求某些道具值之前,我調用了.Refresh()。 當我需要調用.Refresh()時,IT是一種試錯法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.