管理我无法控制的流程的生命周期

时间:2014-09-15 06:39:31

标签: winapi chromium-embedded

我正在使用Chromium Embedded Framework 3(通过CEFGlue)通过插件在第三方进程中托管浏览器。 CEF会旋转各种外部进程(例如渲染器进程)并管理这些进程的生命周期。

当第三方进程干净地退出时,将调用CefRuntime.Shutdown并且所有进程都干净地退出。当第三方进程退出严重时(例如崩溃)我仍然在运行CEF可执行文件,这(有时)会导致主机应用程序出现问题,这意味着它不会再次启动。

我想要一种方法来确保调用主机应用程序退出CefRuntime.Shutdown的任何方式,并且用户不会最终运行虚假进程。

我一直指向工作对象的方向(参见here),但这似乎很难在真正的解决方案中提供,因为在某些版本的Windows上它需要管理权限。

我还可以将CEF设置为在单进程模式下运行,但是文档指定这仅仅是为了“调试”,所以我假设在生产代码中将其运送出于某种原因是不好的(参见{{3} })。

我还有其他选择吗?

继续评论之后,我尝试将主机进程的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循环之后的行永远不会被执行(即使我用{{1替换它'我从来没有看到从这个帖子打印过的任何消息。

1 个答案:

答案 0 :(得分:0)

对于后人,@ 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();