【问题标题】:Managing the lifetime of a process I don't control管理我无法控制的流程的生命周期
【发布时间】:2014-09-15 06:39:31
【问题描述】:

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

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

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

我被指出了作业对象的方向(请参阅here),但这似乎很难在真正的解决方案中发布,因为在某些版本的 Windows 上它需要管理权限。

我也可以将 CEF 设置为在单进程模式下运行,但文档指定这实际上仅用于“调试”,所以我假设在生产代码中交付它出于某种原因是不好的(参见 here) .

我还有什么其他选择?

从 cmets 开始,我尝试将主机进程的 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 替换它我也从来没有查看从该线程打印的更多消息。

【问题讨论】:

  • 为第三方进程创建一个看门狗进程,当应用程序异常终止时触发CefRuntime.Shutdown。看门狗只需要打开一个进程句柄(或者让它传递/复制)和WaitForSingleObject就可以了。

标签: winapi chromium-embedded


【解决方案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();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多