管理我无法控制的流程的生命周期
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();
【讨论】:
以上是关于管理我无法控制的流程的生命周期的主要内容,如果未能解决你的问题,请参考以下文章