Управление временем жизни процесса, который я не контролирую

Я использую Chromium Embedded Framework 3 (через CEFGlue) для размещения браузера на стороннем сервере. процесс через плагин. CEF запускает различные внешние процессы (например, процесс рендеринга) и управляет их временем жизни.

Когда сторонний процесс завершается без ошибок, вызывается CefRuntime.Shutdown, и все процессы завершаются без ошибок. Когда сторонний процесс завершается неудачно (например, происходит сбой), у меня остаются исполняемые файлы CEF, которые все еще работают, и это (иногда) вызывает проблемы с основным приложением, что означает, что оно больше не запускается.

Мне нужен способ гарантировать, что независимо от того, каким образом хост-приложение выходит из CefRuntime.Shutdown, вызывается, и пользователь не запускает ложные процессы.

Мне указали в сторону объектов задания (см. здесь), но похоже, что это может быть сложно реализовать в реальном решении, поскольку в некоторых версиях Windows для этого требуются права администратора.

Я также мог бы настроить CEF для работы в режиме одного процесса, но в документации указано, что это действительно только для «отладки», поэтому я предполагаю, что отправка этого в производственном коде по какой-то причине является плохой (см. здесь).

Какие еще у меня есть варианты?

Следуя комментариям, я попытался передать PID хост-процесса клиенту (я могу сделать это, переопределив OnBeforeChildProcessLaunch). Затем я создал простой сторожевой таймер со следующим кодом:

ThreadPool.QueueUserWorkItem(_ => {
   var process = Process.GetProcessById(pid);
   while (!process.WaitForExit(5000)) {
     Console.WriteLine("Waiting for external process to die...");                     
   }
   Process.GetCurrentProcess().Kill();
});

Я могу проверить в отладчике, что этот код выполняется и что PID, который я ему передаю, правильный. Однако, если я завершаю хост-процесс, я обнаруживаю, что поток просто умирает так, что я не могу его контролировать, и что строки, следующие за циклом while, никогда не выполняются (даже если я заменяю его на Console.WriteLine, я больше не вижу сообщений напечатано из этой ветки.


person Jeff Foster    schedule 15.09.2014    source источник
comment
Создайте сторожевой процесс для стороннего процесса, который запускает CefRuntime.Shutdown в случае аварийного завершения работы приложения. Сторожевой таймер должен только открыть дескриптор процесса (или передать / дублировать его) и _ 2_.   -  person IInspectable    schedule 15.09.2014


Ответы (1)


Для потомков решение, предложенное @IInspectable, работало, но для того, чтобы заставить его работать, мне пришлось переключить реализацию внешнего процесса на использование не многопоточного цикла сообщений.

settings.MultiThreadedMessageLoop = false;
CefRuntime.Initialize(mainArgs, settings, cefWebApp, IntPtr.Zero);

Application.Idle += (sender,e) => {
  if (parentProcess.HasExited) Process.GetCurrentProcess().Kill();
  CefRuntime.DoMessageLoopWork();
}
Application.Run();
person Jeff Foster    schedule 17.09.2014