Как вы узнаете, что подписано на событие в C #? - PullRequest
11 голосов
/ 09 декабря 2010

У меня проблема с утечкой памяти в приложении, над которым я работаю. Опыт научил меня, что одним из первых мест, где собранные мусором языки сталкиваются с утечками памяти, является подписка на события и отказ от их отмены позже. Вторая связана с хранением статического состояния. Я новичок в C # и разочарован непрозрачным типом события.

Мы обнаружили несколько ошибок двойной подписки благодаря удаче розыгрыша, но приложение действительно использует события для ряда вещей. Хотя нам хорошо известен принцип отказа от подписки на все, на что вы подписываетесь, утечки памяти все еще существуют. Я хотел бы систематически определять, что подписано на что.

Edit:

Спасибо за указатель на метод GetInvocationList(). Я пытаюсь создать отладочную систему, которая будет выгружать результаты динамически. Проблема в том, что решения, которые я нашел, работали в .Net 2, но больше не в .Net 3.5. По сути, говорят вам, чтобы получить соответствующее FieldInfo для EventInfo (отражения, GetField и GetEvents соответственно). Однако в .Net 3.5 нет соответствующего FieldInfo, и EventInfo не позволяет мне получить список вызовов.

Я просто хочу вывести список событий и их InvocationList для целей отладки.

Ответы [ 3 ]

6 голосов
/ 09 декабря 2010

Попробуйте использовать метод на event с именем GetInvocationList.

. Это вернет массив делегатов, подписавшихся на событие.

Массив будет содержать делегатов.в порядке их добавления.Это также может быть использовано для выделения и вызова определенных делегатов из списка, тогда как вызов метода event.Invoke вызовет их всех (но даст только возвращаемое значение последнего вызванного делегата)

1 голос
/ 09 декабря 2010

Вы, безусловно, правы, подозревая подписку на событие как причину утечки памяти. Несколько лет назад мы обнаружили проблему, когда статический объект всего приложения подписывался на события страницы ASP.NET - вы можете догадаться, что там произошло.

Еще один способ решения этой проблемы - с точки зрения издателя. Возможно, было бы неудобно заставить всех ваших подписчиков подписаться на рассылку, но если издателя нужно уничтожить / выйти из области видимости, возможно, он может быть запущен, чтобы установить все свои события на нуль - фактически отписав всех и прервав петли.

Если у издателя более длительный срок службы и он поддерживает другие объекты, возможно, вам придется выполнить предложенную ранее процедуру GetInvocationList. Но я бы подумал об этом только для устранения проблемы - выяснения, кто стоит за событиями, когда они не должны.

В крайнем случае вы могли бы рассмотреть какой-то механизм настраиваемой подписки на события на основе WeakReferenced.

0 голосов
/ 18 декабря 2010

См. в этом сообщении в блоге , где вы можете увидеть полезный дамп подписчиков событий в окне Watch.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...