2012-02-17 2 views
2
public class A 
{ 
    public delegate void D(); 
    public event D E; 

    ... 
} 

class B 
{ 
    void Test() 
    { 
     A a = new A(); 
     a.E +=() => { ... }; 

     a = null; 
    } 
} 

Может a быть мусор, когда Test() закончилась или из-за подписки на событии есть еще ссылка на него где-нибудь?C#: действительно подписавшись на событие подразумевает ссылку на объект

+1

http://stackoverflow.com/questions/371109/garbage-collection-when-using-anonymous-delegates-for-event-handling – Krumelur

+0

Closers - это не дублирующий вопрос. Очень разные сценарии. – Oded

+0

Да, это может быть сбор мусора. –

ответ

3

Да, a может быть GC'd в вашем примере. Это также не вызовет никаких проблем. Думаю об этом.

Class1 a = new Class1(); 
Class2 b = new Class2(); 

a.SomeEvent += b.SomeMethod; 

В этом примере a содержит ссылку на b, но не наоборот. Элемент a.SomeEvent похож на List<delegate> (или рядом с ним). Он содержит ссылки на всех подписчиков, поэтому их можно вызвать, когда это необходимо.

Поэтому, когда a должен быть GC'd, это может быть. Он будет уничтожен вместе со списком подписчиков. b останется безжизненным, без проблем.

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

2

Подписываясь на событие на объекте, вы сохраняете ссылку на объект.

Вам необходимо отписаться от подписки, чтобы освободить ссылку.

В вашем случае, как только Test закончил выполнение, ссылка, на которую указывала a, окажется вне сферы действия и будет иметь право на сбор мусора - наличие подписанного мероприятия не изменит это.

См. Мой ответ на Why can .NET not have memory leaks?.

+0

Разве вы не имеете в виду наоборот? Абонент имеет ссылку на абонента. Но если подписчик может быть GC'd, и абонент не может, он получит GC'd. Другими словами, в примере, представленном OP, 'a' может быть собрано мусором, никаких проблем. –

+0

@ Vilx - Вот что я написал. 'a' имеет право на сбор мусора, он будет собирать мусор. – Oded

+0

Извините, меня смутило первое предложение: «Подписавшись на событие на объекте, вы держите ссылку на него». Я понял это наоборот (b подписывается на a и держит ссылку на него). –

Смежные вопросы