2012-11-26 38 views
11

我用Process.Kill()殺死一個進程。就像這樣:如何在沒有得到「進程已退出」異常的情況下終止進程?

if(!process.WaitForExit(5000)) { 
    process.Kill(); 
} 

,有時過程將退出權在字裏行間,所以控制會得到內部if然後Kill將產生一個異常:

System.InvalidOperationException 
Cannot process request because the process (ProcessIdHere) has exited. 
at System.Diagnostics.Process.GetProcessHandle(Int32 access, Boolean throwIfExited) 
at System.Diagnostics.Process.Kill() 
//my code here 

現在包裝的代碼到試戴趕上似乎不是一個好主意,因爲InvalidOperationException可以因其他原因而被調用。

在描述的場景中沒有得到異常的情況下是否有辦法殺死進程?

+0

你有沒有試過檢查內部異常?可能會給你確切的例外處理。 – Yahya

+0

@Yahya:Yeap,內部異常在任何時候都是空的。 – sharptooth

回答

9

你可以的P/Invoke TerminateProcess傳遞Process.Handle。然後手動評估它的原因(GetLastError())。這大致是什麼Process.Kill()內部。

但請注意,TerminateProcess是異步的。所以你必須等待進程句柄以確保完成。 使用 Process.Kill()是爲您的。

更新:更正,Process.Kill()也異步運行。所以你必須使用WaitForExit()來等待終止完成 - 如果你在意的話。

坦率地說,我不打擾。當然,總有一些(遠程)機會出現一些「任意」的代碼行,這與過程不再有關係或對象處於無效狀態無關,而是與現實我想你可以試着圍繞着Kill

此外,根據您的應用程序,您可以考慮記錄此殺死,因爲它似乎是某種最後的手段措施。在這種情況下,用它記錄實際的InvalidOperationException。如果事情變得奇怪,你至少有你的日誌來檢查爲什麼Kill失敗。

綜上所述,您可能也想考慮捕獲/處理Win32Exception出於同樣的原因。

+0

+1爲一個明智的現實世界的方法。 – tomfanning

3

您需要使用HasExited

if(!process.WaitForExit(5000)) 
{ 
    if (!process.HasExited) 
    { 
     process.Kill(); 
    } 
} 

在這裏看到:

http://msdn.microsoft.com/en-us/library/system.diagnostics.process.hasexited.aspx

+4

這仍然有一個競爭條件。 'HasExited'可以返回'false',但是當'Kill'​​執行時,這個過程可能會消失 - 導致InvalidOperationException仍然存在。 –

+1

我們正在談論納秒級的分數,所以看起來不太可能,但如果是這種情況,你無法阻止它,最好你可以做的就是捕捉異常。 – Lloyd

+0

說實話,「納秒級分」似乎誇大其辭。你的過程可能會被搶佔,例如,在兩次調用之間,嘿,這個盒子甚至可能會在一個「不幸的次序」中回來; - 但我同意,捕捉異常是唯一的「強大的」解決方案 - 如果你在乎。 YMMV當然。 –

相關問題