Я надеюсь прояснить некоторые вещи с помощью анонимных делегатов и лямбда-выражений, используемых для создания метода для обработчиков событий на C#, по крайней мере для меня.
Предположим, у нас есть событие, которое добавляет либо анонимного делегата, либо лямбда-выражение (для тех счастливчиков, которые могут использовать более новые версии .NET).
SomeClass.SomeEvent += delegate(object o, EventArg e) { /* do something */ };
Я читал, что в прошлом люди забыли о событиях, у которых все еще есть обработчики, которые предотвращают сборку мусора. Как можно было бы удалить добавленный обработчик, не просто установив SomeEvent в значение null в классе. Разве это не будет совершенно новым обработчиком?
SomeClass.SomeEvent -= delegate(object o, EventArg e) { /* do something */ };
Я мог видеть сохранение анонимного делегата или лямбда-выражения в переменной. Но это, по крайней мере, мне кажется, противоречит самой цели - просто и лаконично добавить обработчик событий.
SomeEventDelegate handler = new SomeEventDelegate(delegate(object o, EventArg e) { /* do something */ });
SomeClass.SomeEvent += handler;
// ... stuff
SomeClass.SomeEvent -= handler;
Опять же, я понимаю, что вы могли бы просто сделать ...
public override Dispose(bool disposing)
{
_someEvent = null;
this.Dispose();
}
Но мне интереснее просто удалить из события динамически созданный метод. Надеюсь, кто-нибудь сможет пролить свет на это для меня. Спасибо!





Я думаю, что проблема в том, что вы, похоже, исходите из предположения, что наличие делегата, назначенного событию объекта, предотвращает его сборку мусора.
Это простое утверждение не соответствует действительности.
С учетом сказанного мнимая проблема исчезает.
Изначально в сборке мусора все является мусором. Сборщик мусора проходит через все, что в настоящее время доступно глобально и в каждом стеке, и от этих других объектов, на которые они ссылаются, и так далее, отмечая каждый как не мусор.
Как такой процесс построения графиков смог бы прийти к этому объекту?
Утверждение верно, поскольку обработчик событий добавляется во внутренне управляемый список обработчиков.
Если вы не будете осторожны, затвор может укусить вас под задницу.
@Will: Вам действительно нужно объясниться. Может быть, с вашим собственным ответом и примером того, как закрытие может так укусить?
@Kent: У вас есть ссылка на этот список обработчиков, управляемый изнутри?
Поищите здесь кусочек задницы: stackoverflow.com/questions/371109/…
Если у объекта X есть обработчик событий, у которого цель является объектом Y, то наличие живого объекта X означает, что объект Y не может быть собран сборщиком мусора. Это не мешает объекту X собираться мусором.
Обычно, когда что-то утилизируют, оно в любом случае быстро превращается в мусор, а это значит, что у вас нет проблем.
Проблема с событиями и сборщиком мусора заключается в том, что вы забыли удалить подписанный обработчик из объекта разные, т.е. у вас есть слушатель, который удаляется, но никогда не будет собираться мусором, потому что все еще существует ссылка на него из события в другом объекте.
Одна из ловушек обработчиков событий делегата заключается в том, что, хотя они кажутся отключенными от классов, в которых они определены, у вас может быть сгенерированное компилятором закрытие, которое не позволяет собирать экземпляры определяющих классов.
Интересный факт: когда ToolStrip становится видимым, он регистрируется в System.UserPreferenceChanged. Поэтому, если вы удалите ToolStrip из его контейнера, не установив для параметра Visible значение false, он никогда не будет удален. Вот почему рано или поздно вам понадобится профилировщик памяти.
Вы не можете.
Точно так же, как вы не можете создать анонимный тип вне его области видимости (за исключением некоторых уловок компилятора).
Вот почему это называется анонимным.
Вам нужно где-то сохранить ссылку ... или использовать отражение.
Я полагаю, что то же самое и с анонимными объектами. SomeClass.SomeEvent + = новый SomeEventHandler (SomeMethod); нельзя было бы удалить, не установив для события значение null, не так ли?
Я имел в виду точно такой же вопрос, и вам удалось его очень ясно выразить.