Попытка найти оставшийся EventHandler, препятствующий выходу контроля из области видимости - PullRequest
4 голосов
/ 09 ноября 2011

Короче говоря, я унаследовал довольно сложное приложение и пытаюсь отследить утечку памяти, связанную с формой. Прямо сейчас, каждый раз, когда форма закрывается и вызывается новая, старая остается в памяти. Я обнаружил проблему со статическим событием, принадлежащим и установленному элементом управления в программе (по-видимому, до тех пор, пока статическое событие было установлено, ни один экземпляр этого элемента управления не считался вне области действия, даже когда никто не ссылался на указанные элементы управления ). Сейчас я пытаюсь отследить оставшуюся проблему.

Используя MemProfiler и ANTS Memory Profile, я узнал, что корневой путь выполнения выглядит следующим образом:

FormOpenWatch        <--       The item which remains active
System.EventHandler -- (this as Delegate)._target
System.Object[]
System.EventHandler -- (this as MultiCastDelegate)._invocationList
System.ComponentModel.EventHandlerList+ListEntry  --  handler
System.ComponentModel.EventHandlerList+ListEntry  --  next
System.ComponentModel.EventHandlerList+ListEntry  --  next
System.ComponentModel.EventHandlerList+ListEntry  --  next
System.ComponentModel.EventHandlerList+ListEntry  --  next
System.ComponentModel.EventHandlerList  --  head
PTU.MdiPTU  --  (this as Component).events        <--       The base application

У кого-нибудь есть понимание того, что я могу искать? Я нашел событие Shown, добавленное с базовым приложением, и гарантировало, что оно удаляется при удалении формы, но, похоже, это не устранило проблему.

Большое спасибо за любую помощь, которую вы можете предоставить.

Позже Редактировать: Я думал, что я успешно решил это несколько раз, и у меня все еще есть проблемы. Кажется, проблема связана с тем, что у моего класса Plotter (и различных производных классов) есть это «открытое статическое событие MouseEventHandler MultiCursorMouseMove;»; событие. У нас есть «курсор», который отображает значение и время графика на месте мыши. Первоначально это работало на одном графике за раз, но был сделан запрос, чтобы позволить пользователю переключать режим, в котором перемещение мыши перемещало график по всем отображаемым графикам. Я записал первоначальную процедуру подключения EventHandlers, когда элементы были созданы, и мой партнер по пруду переписал его, чтобы использовать статическое событие, которое назначается каждому элементу в процессе строительства. Его путь намного элегантнее и работает лучше. Все, кроме того, что это привело к утечкам памяти. Использование программного обеспечения для профилирования памяти показало, что каждый раз, когда я пытаюсь избавиться от формы, содержащей графики, у меня остается ряд случаев «Уничтоженный экземпляр с прямыми корнями EventHandler». В каждом из них это показывает, что объект является либо Плоттером, либо объектом, на который указывает Плоттер. И в каждом из них базовая ссылка состоит в том, что MultiCursorMouseMove EventList указывает на эти объекты. Я думаю, что происходит то, что плоттер остается живым, потому что у него есть это статическое событие, которое, в свою очередь, связано с плоттерами. Мне удалось проверить, что MultiCursorMouseMove имеет значение null через отладчик в заданной точке благодаря моему коду Dispose, удаляющему событие для каждого плоттера, и все же при запуске профилировщика в той же точке все еще отображается эта цепочка из MultiCursorMouseMove для этих классов.

У меня нет идей о том, как это исправить в настоящее время. Кто-нибудь?

1 Ответ

1 голос
/ 09 ноября 2011

Если MdiPTU является родительской формой MDI для вашего приложения, похоже, что FormOpenWatch подписался на одно из своих событий.Если это не было сделано напрямую, вы можете найти подписку в суперклассе FormOpenWatch или, возможно, даже в другом коде, который может подключить выполнение метода FormOpenWatch из события MdiPTU.

...