【问题标题】:How to kill a process without getting a "process has exited" exception?如何在没有“进程已退出”异常的情况下终止进程?
【发布时间】:2012-11-13 22:01:37
【问题描述】:

我使用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

现在将代码包装到 try-catch 中似乎不是一个好主意,因为可以出于其他原因调用 InvalidOperationException

在所描述的场景中,有没有办法杀死一个进程而不会出现异常?

【问题讨论】:

  • 你试过检查内部异常吗?可能会给你确切的例外来处理。
  • @Yahya:是的,内部异常始终为空。

标签: c# .net process


【解决方案1】:

你需要使用HasExited:

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

看这里:

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

【讨论】:

  • 那仍然有竞争条件。 HasExited 可能会返回 false,但当 Kill 执行时,该过程可能会消失 - 仍然会导致 InvalidOperationException
  • 我们说的是几分之一纳秒,所以这似乎不太可能,但如果是这种情况你无法阻止它,你能做的最好的就是捕获异常。
  • “纳秒的分数”老实说似乎有些夸张。您的进程可能会被抢占,例如,在两个调用之间,哎呀,盒子甚至可能在以“不幸的顺序”恢复之间休眠;-) 但我同意,捕捉异常是唯一的“强大”解决方案 - 如果你在乎的话。当然是 YMMV。
  • 好吧,我只是说机会很小。这是一个很小的机会,但应该处理:)
【解决方案2】:

您可以 P/Invoke TerminateProcess 传递它 Process.Handle。然后手动评估它的原因(GetLastError())。这大致就是Process.Kill() 在内部所做的。

但请注意,TerminateProcess 是异步的。所以你必须等待进程句柄以确保它完成。 使用Process.Kill() 可以为您做到这一点。

更新: 更正,Process.Kill() 也是异步运行的。所以你必须使用WaitForExit() 等待终止完成 - 如果你在乎的话。

坦率地说,我不会打扰。当然,总是有(远程?)一些“任意”InvalidOperationExcepion 从该代码行冒出的可能性,这与不再存在的进程或Process 对象无效无关状态,但实际上我认为您可以在 Kill 周围使用 try/catch。

此外,根据您的应用程序,您无论如何都可以考虑记录此杀戮,因为这似乎是某种最后的手段。在这种情况下,用它记录实际的InvalidOperationException。如果事情变得奇怪,你至少有你的日志来检查 Kill 失败的原因。

说了这么多,出于同样的原因,您可能还想考虑捕获/处理Win32Exception

【讨论】:

    猜你喜欢
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    • 2014-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多