1

I want my child process to tidy itself up if its parent exits. Currently I'm hanging on the Process.Exited method:

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

I'm assuming that I need to keep parent in scope until I'm no longer interested in the Exited event. Is that the case?

Tim Barrass
  • 4,813
  • 2
  • 29
  • 55
  • Hans, thanks; I realize you're not hurting for SO kudos but if you answer I can accept. For my future reference, the best _other_ ref to this I've seen so far is in Jeffrey Richter's CLR via C# 3, in which he talks about RegisteredWaitHandle holding a handle to a kernel object that the thread pool is waiting on. – Tim Barrass Dec 19 '11 at 20:31

2 Answers2

2

No, the Process class is smart about this. It internally uses the RegisteredWaitHandle class. Which is primarily used to ensure that the Exited event is raised. But also keeps a live reference to the parent object so it doesn't get garbage collected.

There are other classes in the framework that work like this, using various means to maintain the reference. A Winforms Form is a good example, a typical Winforms app never keeps a reference to the main form. It is kept alive by an internal table that maps handles to objects. The user closing the form kills the handle which gets it removed from that table which allows garbage collection.

A System.Timers.Timer is another one, kept alive by a cookie object that the CLR actually has knowledge of and keeps referenced while the timer is enabled. But not a System.Threading.Timer as a counter-example, it gets garbage collected while it is enabled if you don't keep a reference to it yourself.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
0

You don't have to keep your Process instance in scope, because you have a listener that is attached to an event so it prevents the garbage collector to free your instance. Here is a sample that demonstrates this:

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");
            };
    }
}

Output is:

Stared notepad
Wait complete

(user closes notepad)

Notepad exited
ken2k
  • 48,145
  • 10
  • 116
  • 176
  • Hi ken2k -- actually, I'm not sure that's the case. IIRC just having a subscriber to an event doesn't keep the publisher alive: see e.g. http://stackoverflow.com/a/774203/389828 – Tim Barrass Dec 19 '11 at 17:10