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

Posted

技术标签:

【中文标题】管理我无法控制的流程的生命周期【英文标题】: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就可以了。 【参考方案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();

【讨论】:

以上是关于管理我无法控制的流程的生命周期的主要内容,如果未能解决你的问题,请参考以下文章

Oracle PLM的产品协同功能如何管理产品的生命周期的?

2021-05-31 aps实现高效的生命周期管理

Fragment生命周期

Devops下的接口全生命周期管理与测试

一个BPMN流程示例带你认识项目中流程的生命周期

Tomcat——Tomcat启动流程