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

366
17 января 2017, 22:13

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

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

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

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

Answer 1

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

Во-вторых, если под onClose вы понимаете стандартное событие - то присвоить ему null вы не сможете. А заводить свое событие - смысла мало.

В-третьих, начиная с .NET 4.5 появилось новое удобное средство для отслеживания однократных событий - задачи (точнее, они появились в 4.0, но удобными стали в 4.5).

Если форма предназначена для однократного показа, то можно сделать примерно так:

private readonly TaskCompletionSource<bool> tcsClosed = new TaskCompletionSource<bool>();
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, чтобы никому не пришло в голову что обработчиков может быть несколько.

READ ALSO
Можно ли использовать куки, чтобы потом не вводить капчу?

Можно ли использовать куки, чтобы потом не вводить капчу?

ИСПОЛЬЗУЕТСЯ: С#, WebDriver (при необходимости)

318
Метод Rollback EntityFramework

Метод Rollback EntityFramework

Подскажите, пожалуйста, как реализовать Rollback используя EntityFramework 6x, а так же паттерн Unit of work

316
Передача данных между двумя DataGridView

Передача данных между двумя DataGridView

На форме есть два dataGridViewВ первом отображается поиск из базы, во второй должны записываться необходимые строки из результата поиска

443
Как сократить логическое выражение?

Как сократить логическое выражение?

Можно ли как нибудь переписать вот это условие в более короткий вариант?

333