Определение объема, чтобы убедиться, что Process.Exited получен - PullRequest
1 голос
/ 19 декабря 2011

Я хочу, чтобы мой дочерний процесс приводил себя в порядок, если родительский процесс завершается.В настоящее время я использую метод Process.Exited:

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

Я предполагаю, что мне нужно сохранить область действия parent, пока я не перестану интересоваться событием Exited.Это тот случай?

Ответы [ 2 ]

2 голосов
/ 20 декабря 2011

Нет, класс Process умен в этом.Он внутренне использует класс RegisteredWaitHandle.Который в первую очередь используется, чтобы гарантировать, что событие Exited вызвано.Но также сохраняет живую ссылку на родительский объект, чтобы он не собирал мусор.

В фреймворке есть другие классы, которые работают подобным образом, используя различные средства для поддержки ссылки,Хорошим примером является форма Winforms, типичное приложение Winforms никогда не сохраняет ссылку на основную форму.Он поддерживается живой внутренней таблицей, которая сопоставляет дескрипторы с объектами.Пользователь, закрывающий форму, убивает дескриптор, который удаляет ее из этой таблицы, что позволяет собирать мусор.

Еще один объект System.Timers.Timer, поддерживаемый объектом cookie, о котором CLR фактически знает исохраняет ссылки, пока таймер включен.Но не System.Threading.Timer в качестве контрпримера, он собирает мусор, пока он включен, если вы сами не сохраняете ссылку на него.

0 голосов
/ 19 декабря 2011

Вам не нужно держать свой экземпляр 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
...