簡體   English   中英

System.Diagnostics.Process.Start奇怪的行為

[英]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的應用程序。
  • 您指定等待的時間,如果進程在該時間范圍內達到空閑狀態,則該方法返回bool,顯然,如果需要,您可以使用它循環,或者根據需要進行處理。

希望有幫助:)

我認為增強對_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM