Не вызовет ли следующая ситуация отказа от подписки на событие через закрытие? - PullRequest
5 голосов
/ 03 ноября 2011

Рассмотрим ситуацию, в которой вы хотите подписаться на событие для одного и только одного уведомления. Как только появится первое уведомление, вы отмените подписку на все будущие события. Будет ли следующий шаблон представлять проблемы с памятью? Это работает, но я не был уверен, что закрывающая ссылка может хранить вещи в памяти дольше, чем хотелось бы.

public class Entity
{
    public event EventHandler NotifyEvent;
}

// And then, elsewhere, for a listen-once handler, we might do this:
Entity entity = new Entity();
Action<object, EventArgs> listener = null;
listener = (sender, args) =>
{
    // do something interesting
    // unsubscribe, so we only get 1 event notification
    entity.NotifyEvent -= new EventHandler(listener);
};
entity.NotifyEvent += new EventHandler(listener);

Обратите внимание, что вы должны объявить 'listener' и присвоить значение (null). В противном случае компилятор жалуется на «Использование неназначенной локальной переменной listener»

Ответы [ 2 ]

6 голосов
/ 03 ноября 2011

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

4 голосов
/ 03 ноября 2011

Хотя я думаю, что общий шаблон в порядке, я бы не прошел Action<object, EventArgs>. Я бы использовал:

EventHandler listener = null;
listener = (sender, args) =>
{
    // do something interesting
    // unsubscribe, so we only get 1 event notification
    entity.NotifyEvent -= listener;
};
entity.NotifyEvent += listener;
...