2012-11-26 7 views
11

Ich verwende Process.Kill(), um einen Prozess zu beenden. Wie folgt aus:Wie kann ein Prozess abgebrochen werden, ohne dass eine Ausnahme "Prozess wurde beendet" angezeigt wird?

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

und manchmal wird der Prozess verlassen direkt zwischen den Zeilen, so Steuerung innerhalb if und dann Kill wird ergeben eine Ausnahme:

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 

Nun Umwickeln Sie den Code in TRY Fang scheint keine gute Idee zu sein, denn InvalidOperationException kann aus anderen Gründen aufgerufen werden.

Gibt es eine Möglichkeit, einen Prozess zu beenden, ohne eine Ausnahme in dem beschriebenen Szenario zu bekommen?

+0

Haben Sie versucht, die interne Ausnahme zu überprüfen? Könnte Ihnen eine genaue Ausnahme geben. – Yahya

+0

@Yahya: Yeap, innere Ausnahme ist zu allen Zeiten null. – sharptooth

Antwort

9

Sie könnten P/Invoke TerminateProcess es Process.Handle vorbei. Dann die Ursache manuell auswerten (GetLastError()). Was ist ungefähr, was Process.Kill() intern tut.

Beachten Sie jedoch, dass TerminateProcess asynchron ist. Sie müssen also auf das Prozess-Handle warten, um sicher zu sein, dass es erledigt ist. Mit Process.Kill() macht das für Sie.

Update: Korrektur, Process.Kill() läuft auch asynchron. Also müssen Sie WaitForExit() verwenden, um auf Beendigung zu warten - wenn Sie sich interessieren.

Ehrlich gesagt würde ich nicht stören. Natürlich gibt es immer die (entfernte?) Chance, dass irgendeine "willkürliche" InvalidOperationExcepion aus dieser Codezeile herausspringt, die nicht damit verbunden ist, dass der Prozess nicht mehr da ist oder das Process Objekt in einem ungültigen Zustand ist, aber in Ich denke, du kannst einfach mit dem Versuch/Fang um die Kill gehen.

Darüber hinaus könnten Sie, je nach Ihrer Anwendung, in Erwägung ziehen, diesen Kill trotzdem zu protokollieren, da er als eine Art Last-Resort-Maßnahme erscheint. In diesem Fall loggen Sie den aktuellen InvalidOperationException damit ein. Wenn die Dinge seltsam sind, haben Sie zumindest Ihre Protokolle zu überprüfen, warum die Kill fehlgeschlagen ist.

Mit allem, was Sie gesagt haben, möchten Sie vielleicht auch in Betracht ziehen/Handhabung Win32Exception aus den gleichen Gründen.

+0

+1 für eine vernünftige Real-World-Ansatz. – tomfanning

3

Sie müssen HasExited verwenden:

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

Siehe hier:

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

+4

Das hat immer noch eine Wettlaufbedingung. 'HasExited' kann' false' zurückgeben, aber zu dem Zeitpunkt, an dem 'Kill' ​​ausgeführt wird, könnte der Prozess weg sein - was zu einer' InvalidOperationException' führt. –

+1

Wir sprechen Bruchteile einer Nanosekunde, das scheint unwahrscheinlich, aber wenn das der Fall ist, können Sie es nicht stoppen, am besten können Sie die Ausnahme fangen. – Lloyd

+0

"Bruchteile von Nanosekunden" scheint, um ehrlich zu sein, eine Übertreibung. Ihr Prozess könnte zum Beispiel zwischen den beiden Aufrufen vorgezogen werden, zum Teufel, die Box könnte sogar in Ruhe zwischendurch wieder in einer "unglücklichen Reihenfolge" auftauchen ;-) Aber ich stimme zu, dass das Einfangen der Ausnahme das einzige "robuste" ist Lösung - wenn es dich interessiert. YMMV natürlich. –

Verwandte Themen