我开始应该大致如下定义的超时时间内结束一个子进程:子进程长存
using (Process process = process.Start(startInfo))
{
if (!process.WaitForExit(timeOutMilliSeconds))
{
if (!process.HasExited())
{
process.Kill();
}
}
}
子进程是CPU密集型计算引擎(一SAT解算器)。我的主程序是用C#
编写的,使用的是Visual Studio 2013和Windows 7 64位。
大多数情况下,上面的代码工作正常的进程超时终止已完成。但在约5%的案例中,process.Kill()
没有明显的效果。儿童进程保持活跃。
我试图以较低的优先级启动子进程。在杀死它之前,我也试图暂停它。作为外部工具调用TASKKILL /F
也并不总是有帮助。我注意到,所有SAT求解器都不会出现这个问题。我有管理权限,但不要以管理员身份运行主程序。
我该怎么做才能可靠地终止我的应用程序的子进程?
编辑:
除了超过其超时的预算,子进程的行为很正常,可以使用手动的Process Explorer(无管理员高程)被杀死。问题是如何确保在超时后没有进程继续运行。
解决方法:
我已经实现了使用VC++ 2013超时工具。我不是直接调用子进程,而是调用我的工具,然后调用子进程。该工具正在使用CreateProcess()和TerminateProcess()来启动和停止子进程。 可能直接从C#
程序中调用CreateProcess()和TerminateProcess()而不产生额外的过程。
解决方法并不高雅,但它确实解决了我的问题。
在Windows中,并不是所有的IO是撤销。如果进程有不可撤销的未完成的IO,它们可以进入一个不可驱动的僵尸状态。虽然这是非常罕见的。 – usr
从'Kill'的文档:“Kill方法异步执行。调用Kill方法后,调用WaitForExit方法等待进程退出,或者检查HasExited属性以确定进程是否已退出。 –
另外,尝试捕获来自Kill的异常,可能是因为您的应用也正在终止而导致异常被抛出,并且您没有看到异常。 –