Я начинаю дочерний процесс, который должен заканчиваться в течение определенного периода ожидания по следующим строкам:
using (Process process = process.Start(startInfo))
{
if (!process.WaitForExit(timeOutMilliSeconds))
{
if (!process.HasExited())
{
process.Kill();
}
}
}
Детский процесс - это процессор с интенсивным вычислением CPU (решатель SAT). Моя основная программа написана на C#
и разработана с использованием 64-разрядной версии Visual Studio 2013 и Windows 7.
В большинстве случаев приведенный выше код работает и завершается окончательное завершение процесса. Но в около 5% случаев process.Kill()
не имеет видимого эффекта. Детский процесс остается активным.
Я попытался запустить дочерний процесс с более низким приоритетом. Я также попытался приостановить его, прежде чем убить его. Вызов TASKKILL/F
как внешнего инструмента также не всегда помог. Я заметил, что проблема не возникает для всех решателей SAT. У меня есть права администратора, но не запускайте основную программу как Администратор.
Что я могу сделать для надежного завершения дочернего процесса моего приложения?
Отредактировано:
Помимо превышения их бюджета тайм-аута, дочерние процессы ведут себя вполне нормально и могут быть убиты вручную с помощью Process Explorer (без повышения уровня администратора). Вопрос заключается в том, как убедиться, что ни один процесс не будет запущен после таймаута.
Временное решение:
Я применил тайм-аут с использованием VC++ 2013. Вместо прямого вызова дочернего процесса я теперь вызываю свой инструмент, который в свою очередь вызывает дочерний процесс. Инструмент использует CreateProcess() и TerminateProcess() для запуска и остановки дочернего процесса. Вероятно, можно вызвать CreateProcess() и TerminateProcess() из программы C#
напрямую, не создавая дополнительный процесс.
Обходной путь не изящный, но он решает мою проблему.
Я создал библиотеку управления дочерними процессами, где отслеживается родительский процесс и дочерний процесс из-за двунаправленного WCF-канала. Если либо дочерний процесс завершается, либо прерывается родительский процесс, он уведомляется. Существует также доступный помощник отладчика, который автоматически присоединяет отладчик VS к запущенному дочернему процессу.
Возможно, вы можете использовать его для управления вашим дочерним процессом.
Сайт проекта:
http://www.crawler-lib.net/child-processes
Пакеты NuGet:
https://www.nuget.org/packages/ChildProcesses https://www.nuget.org/packages/ChildProcesses.VisualStudioDebug/
Kill
: «Метод Kill выполняется асинхронно. После вызова метода Kill вызовите метод WaitForExit, чтобы дождаться завершения процесса, или проверьте свойство HasExited, чтобы определить, завершился ли процесс.