确定收到Process.Exited的范围确定

时间:2011-12-19 16:29:09

标签: c# child-process

如果父母退出,我希望我的孩子进程能够整理自己。目前我挂在Process.Exited方法上:

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

我假设我需要将parent保留在范围内,直到我不再对退出事件感兴趣为止。是这样的吗?

2 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分: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