Сборщик мусора и обработчики событий - PullRequest
8 голосов
/ 13 июля 2011

Быстрый вопрос.Скажем, что у меня есть класс, реализованный как в примере ниже.

class Subscriber
{
    private Publisher publisher = new Publisher;


    public Subscriber()
    {
       publisher.SomeEvent += new EventHandler(OnEventFired);
    }

    private void OnEventFired(object sender, EventArgs e)
    {
    }

}

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

public void DoSomething()
{
    Subscriber subscriber = new Subscriber();
}

Правильно ли я ожидать, чтоэто может привести к утечке памяти, так как подписчик никогда не отписывается от события издателей, что приводит к тому, что они оба поддерживают сильную ссылку друг на друга?

Ответы [ 2 ]

16 голосов
/ 13 июля 2011

Это не приведет к утечке - ГХ может обрабатывать циклические ссылки без проблем.

Однако это будет означать, что издатель будет эффективно иметь ссылку на подписчика,поэтому подписчик не может собирать мусор до тех пор, пока издатель не получит право на сборку мусора или не откажется от подписки на событие.

2 голосов
/ 18 июля 2011

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

Одна из моих проблем с .net - Microsoft не поддерживает очистку событий.Это особенно раздражает в vb.net, который гарантирует, что изменение переменной «WithEvents» будет правильно генерировать надлежащие подписки и неподписки, но не предоставляет удобного способа обработчику IDisposable отписаться от всех событий, содержащихся в объекте.

...