Страницы

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

четверг, 2 января 2020 г.

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

#c_sharp


Здравствуйте!

Подскажите пожалуйста равносильны ли будут по значению эти 2 события.

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

Событие 2:
Создаем windows form, подписываемся с помощью делегата на событие о ее закрытии:
form.onClose += incomeCloseEvent;
после закрытия формы в её деструкторе я обнулю ссылку:
this.onClose = null;
    


Ответы

Ответ 1



Во-первых, нет никакого смысла отписываться от событий уничтожаемого объекта. Во-вторых, если под 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, чтобы никому не пришло в голову что обработчиков может быть несколько.

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

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