EventHandlers и анонимные делегаты/выражения лямбда
Я надеюсь прояснить некоторые вещи с анонимными делегатами и лямбда-выражениями, которые используются для создания метода обработчиков событий в С#; для меня как минимум.
Предположим, что у нас есть событие, которое добавляет анонимный делегат или выражение лямбда [для вас, счастливые толпы, которые могут использовать более новые версии .NET).
SomeClass.SomeEvent += delegate(object o, EventArg e) { //do something };
Я читал, что люди в прошлом забыли о событиях, которые по-прежнему имеют обработчики, которые мешают сбору мусора. Как можно было бы удалить добавленный обработчик, просто не установив SomeEvent в null в классе. Не будет ли это совсем новым обработчиком?
SomeClass.SomeEvent -= delegate(object o, EventArg e) { //do same thing };
Я мог видеть сохранение анонимного выражения делегата/лямбда в переменной, но это, по крайней мере, для меня, по-видимому, лишает всю цель возможности просто и лаконично добавить обработчик событий.
SomeEventDelegate handler = new SomeEventDelegate(delegate(object o, EventArg e) { //do same thing });
SomeClass.SomeEvent += handler;
//... stuff
SomeClass.SomeEvent -= handler;
Опять же, я понимаю, что вы могли бы просто сделать...
public override Dispose(bool disposing)
{
_someEvent = null;
this.Dispose();
}
Но мне интереснее просто удалить динамически созданный метод из Event. Надеюсь, кто-то может пролить свет на это для меня. Спасибо!
Ответы
Ответ 1
Если объект X имеет обработчик события, целью которого является объект Y, тогда объект X, являющийся живым, означает, что объект Y не может быть собранным мусором. Это не останавливает объект X от сбора мусора.
Обычно, когда что-то есть, оно все равно становится мусором, что означает, что у вас нет проблемы.
Проблема с событиями и GC - это если вы забыли удалить подписанный обработчик из другого объекта - то есть у вас есть слушатель, который находится, но никогда не будет собираться мусором, потому что все еще есть ссылка на него из события в другой объект.
Ответ 2
Я думаю, проблема в том, что вы, похоже, исходите из предположения, что наличие делегата, назначенного для события объекта, не позволяет GCed.
Это простое утверждение неверно.
Сказав, что воспринимаемая проблема исчезает.
Изначально в сборке мусора все это мусор. GC проходит через все доступные в настоящее время глобально и в каждом стеке и из этих других объектов, на которые они ссылаются, и т.д., Отмечая каждый как не мусор.
Как бы такой процесс графического отображения удалось достичь этого объекта?
Ответ 3
Вы не можете.
Так же, как вы не можете создать анонимный тип вне своей области (за исключением некоторых трюков компилятора).
Вот почему он называется анонимным.
Вам нужно сохранить ссылку где-нибудь... или использовать отражение.