1

我希望我的子进程在其父进程退出时自行整理。目前我挂在 Process.Exited 方法上:

var parent = Process.GetProcessById(ParentPID);
parent.EnableRaisingEvents = true;
parent.Exited += ActOnParentExit;

我假设我需要保持parent在范围内,直到我不再对 Exited 事件感兴趣。是这样吗?

4

2 回答 2

2

不, Process 类对此很聪明。它在内部使用 RegisteredWaitHandle 类。这主要用于确保引发 Exited 事件。但也保持对对象的实时引用,因此它不会被垃圾收集。

框架中还有其他类也是这样工作的,使用各种方法来维护引用。Winforms 表单就是一个很好的例子,典型的 Winforms 应用程序从不保留对主表单的引用。它由一个将句柄映射到对象的内部表保持活动状态。关闭表单的用户会杀死将其从允许垃圾收集的表中删除的句柄。

System.Timers.Timer 是另一个,由 CLR 实际上知道并在启用计时器时保持引用的 cookie 对象保持活动状态。但不是 System.Threading.Timer 作为反例,如果您自己不保留对它的引用,它会在启用时收集垃圾。

于 2011-12-19T20:48:00.850 回答
0

您不必将 Process 实例保留在范围内,因为您有一个附加到事件的侦听器,因此它可以防止垃圾收集器释放您的实例。这是一个示例,演示了这一点:

private static void Main(string[] args)
{
    Process.Start("notepad");

    Console.WriteLine("Started notepad");
    Wait();
    Console.WriteLine("Wait complete");

    Console.ReadKey();
}

private static void Wait()
{
    Process myProcess = Process.GetProcessesByName("notepad").FirstOrDefault();
    if (myProcess != null)
    {
        myProcess.EnableRaisingEvents = true;
        myProcess.Exited += (sender, e) =>
            {
                Console.WriteLine("Notepad exited");
            };
    }
}

输出是:

Stared notepad
Wait complete

(用户关闭记事本)

Notepad exited
于 2011-12-19T17:01:08.813 回答