Страницы

Поиск по вопросам

среда, 9 января 2019 г.

Отписка от событий(слабые события)

Здравствуйте!
Подскажите пожалуйста равносильны ли будут по значению эти 2 события.
Событие 1: Создаем windows form, подписываемся с помощью делегата на событие о её закрытии: form.onClose += incomeCloseEvent; после закрытия будет вызвана функция incomeCloseEvent() в которой я обнуляю ссылку: form.onClose -= incomeCloseEvent;
Событие 2: Создаем windows form, подписываемся с помощью делегата на событие о ее закрытии: form.onClose += incomeCloseEvent; после закрытия формы в её деструкторе я обнулю ссылку: this.onClose = null;


Ответ

Во-первых, нет никакого смысла отписываться от событий уничтожаемого объекта.
Во-вторых, если под onClose вы понимаете стандартное событие - то присвоить ему null вы не сможете. А заводить свое событие - смысла мало.
В-третьих, начиная с .NET 4.5 появилось новое удобное средство для отслеживания однократных событий - задачи (точнее, они появились в 4.0, но удобными стали в 4.5).
Если форма предназначена для однократного показа, то можно сделать примерно так:
private readonly TaskCompletionSource tcsClosed = new TaskCompletionSource();
protected override void OnClosed(object sender, System.EventArgs e) { base.OnClosed(sender, e); tcsClosed.SetResult(true); }
public Task ShowAsync() => ShowAsync(CancellationToken.None);
public async Task ShowAsync(CancellationToken token) { if (tcsClosed.Task.IsCompleted) throw new InvalidOperationException("Форма уже была показана"); using (token.Register(Close, useSynchronizationContext: true)) { Show(); await tcsClosed.Task; } token.ThrowIfCancellationRequested(); }
Теперь в асинхронном методе можно показать форму и дождаться ее закрытия при помощи одного оператора await form.ShowAsync()
Если одну и ту же форму можно показывать несколько раз - надо перенести инициализацию поля tcsClosed в первую строчку метода ShowAsync, заменив условный оператор.
Никаких событий и отписки от них!

По теме же вопроса - очевидно, вариант -= incomeCloseEvent отписывает один обработчик, а вариант = null отписывает все обработчики.
Если гарантируется, что обработчик будет только один - эти два варианта эквивалентны. Но тогда и подписку лучше делать тоже через оператор присваивания: form.onClose = incomeCloseEvent, чтобы никому не пришло в голову что обработчиков может быть несколько.

Комментариев нет:

Отправить комментарий