Следует ли использовать агрегатор событий только для предотвращения утечек памяти? - PullRequest
2 голосов
/ 17 июля 2011

Мы рассматриваем использование агрегатора событий Prism с целью уменьшения утечек памяти из-за ссылок на события.

  1. Является ли это самой веской причиной для использованияэтот шаблон?Другие преимущества нам сейчас не интересны.Мы планируем использовать его между компонентами модели, а не пользовательским интерфейсом.

  2. Наша проблема заключалась в том, что некоторые разработчики забыли отменить регистрацию событий.Я видел, что у Prism есть одна разновидность, которая использует слабые ссылки, но имеет ограничения .Другая разновидность заставляет явно отменить подписку (), что опять же можно забыть.Так как же лучше?

1 Ответ

6 голосов
/ 17 июля 2011

Наша проблема состояла в том, что некоторые разработчики забыли отменить регистрацию событий

Если это ваша проблема, переключение на агрегатор событий Prism (или, используя любую другую реализацию) не улучшит ситуацию.

Добавление новой зависимости с новым, нетривиальным шаблоном использования в беспорядочную ситуацию совсем не приведёт в порядок.

То, что вам нужно для очистки вашего кода.

Вместо новых библиотек кода, я бы посоветовал изучить инструменты статического анализа, такие как fxCop (он же Code Analysis), Gendarme и NDepend .Все они способны обнаруживать некоторые ситуации, когда события не отсоединены или IDisposable не реализован должным образом.

Используя статический анализ, вы можете беспристрастно идентифицировать код, который нуждается в очистке.Используйте профилировщик памяти (например, dotTrace Memory ), и вы сможете быстро найти самых злостных нарушителей и быстро их очистить.

Обновление

В ответена вопрос в комментарии ниже:

Что вы предлагаете в качестве хорошего шаблона для обеспечения того, чтобы события были отцеплены?

В может быть трудно убедиться, что всесобытия отписываются - но учитывая способ их реализации (см. CLR через C # ), вы можете немного обмануть, убедившись, что все подписки на события отбрасываются.

вместо

public event EventHandler<Fu> FuBar;

обрабатывайте подписку на события самостоятельно, например:

public event EventHandler<Fu> FuBar {
    add { mFuBar += value; }
    remove { mFuBar -= value; }
}

private EventHandler<Fu> mFuBar;

Затем внедрите IDisposable в своем классе и в своем методе Dispose() установите mFuBar в null, отбрасывая подписки.FxCop (и другие инструменты) могут затем сказать вам, если вы не можете удалить класс.

...