Скажите, если я прислушиваюсь к событию:
Subject.NewEvent += delegate(object sender, NewEventArgs e)
{
//some code
});
Как мне отменить регистрацию этого события? Или просто допустить утечку памяти?
Скажите, если я прислушиваюсь к событию:
Subject.NewEvent += delegate(object sender, NewEventArgs e)
{
//some code
});
Как мне отменить регистрацию этого события? Или просто допустить утечку памяти?
Если вам нужно отменить регистрацию события, я рекомендую избегать использования анонимных делегатов для обработчика событий.
Это тот случай, когда лучше назначить это локальному методу - вы можете полностью отказаться от подписки на событие.
IDisposable
, и вы сможете легко очистить все свои обработчики событий.
- person Enigmativity; 04.10.2011
Дайте вашему экземпляру анонимного делегата имя:
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);
}
}
}
}
someClass.SomeEvent = null
вместо повторения мысли InvocationList.
- person einord; 21.09.2017
Вам нужно имя для вашей анонимной функции, и тогда вы можете делать это только до тех пор, пока имя находится в области видимости:
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;
Вам нужно отменить регистрацию по какой-либо причине, кроме утечки?
Что касается бита «Или просто разрешить утечку памяти», когда Subject очищается сборщиком мусора, ваш анонимный делегат также должен быть очищен, поэтому утечки быть не должно.
Есть еще один (мой) вопрос, который затрагивает это с некоторыми (слишком подробными) деталями: Слабая модель обработчика событий для использования с лямбдами.
Однако теперь, когда Reactive Framework вышел, я бы серьезно подумал о том, чтобы изучить это в такой ситуации.