Скажите, если я слушаю событие:
Subject.NewEvent += delegate(object sender, NewEventArgs e)
{
//some code
});
Теперь, как я могу зарегистрировать это событие? Или просто пропустить утечку памяти?
Скажите, если я слушаю событие:
Subject.NewEvent += delegate(object sender, NewEventArgs e)
{
//some code
});
Теперь, как я могу зарегистрировать это событие? Или просто пропустить утечку памяти?
Если вам нужно отменить регистрацию события, я рекомендую избегать анонимных делегатов для обработчика событий.
Это один случай, когда присвоение этого локальному методу лучше - вы можете отписаться от события чисто.
Дайте вашему экземпляру анонимного делегата имя:
EventHandler<NewEventArg> handler = delegate(object sender, NewEventArgs e)
{
//some code
};
Subject.NewEvent += handler;
Subject.NewEvent -= handler;
Чтобы удалить обработчик при первом вызове:
//SubjectType Subject = ..... already defined if using (2)
EventHandler handler = null;
handler = delegate(object sender, EventArgs e)
{
// (1)
(sender as SubjectType).NewEvent -= handler;
// or
// (2) Subject.NewEvent -= handler;
// do stuff here
};
Subject.NewEvent += handler;
Вы можете создать метод для отмены регистрации всех слушателей события. Это не совсем то, что вы хотите, но иногда это может быть полезно. Например (это действительно работает =)):
class Program {
static void Main(string[] args) {
A someClass = new A();
someClass.SomeEvent += delegate(object sender, EventArgs e) {
throw new NotImplementedException();
};
someClass.ClearEventHandlers();
someClass.FireEvent();
Console.WriteLine("No error.");
}
public class A {
public event EventHandler SomeEvent;
public void ClearEventHandlers() {
Delegate[] delegates = SomeEvent.GetInvocationList();
foreach (Delegate delegate in delegates) {
SomeEvent -= (EventHandler) delegate;
}
}
public void FireEvent() {
if (SomeEvent != null) {
SomeEvent(null, null);
}
}
}
}
Вам нужно имя для вашей анонимной функции, и тогда вы можете делать это только до тех пор, пока имя находится в области видимости:
var handler = new EventHandler(delegate(object o, EventArgs e)
{
//do something...
};
Subject.NewEvent += handler;
// later on while handler is still in scope...
Subject.NewEvent -= handler;
Вам нужно отменить регистрацию по какой-либо причине, кроме утечки?
Что касается бит "Или просто разрешить утечку памяти", когда объект очищается сборщиком мусора, ваш анонимный делегат также должен быть очищен, поэтому утечки не должно быть.
Есть еще один вопрос (мой), который затрагивает это в некоторых (слишком много) деталях: Слабая модель обработчика событий для использования с lambdas.
Однако теперь, когда вышел Reactive Framework, серьезно рассмотрим вопрос о том, что в такой ситуации.