Hello!

Please tell me whether these 2 events are equivalent in meaning.

Event 1: Create a windows form, subscribe to the closing event with the help of the delegate: form.onClose += incomeCloseEvent; after closing, the function incomeCloseEvent() will be called in which I zero the link: form.onClose -= incomeCloseEvent;

Event 2: Create a windows form, subscribe to the closing event with a delegate: form.onClose += incomeCloseEvent; after closing the form in its destructor, I will reset the link: this.onClose = null;

  • Essentially yes. Equivalently. - Kryshtop
  • one
    "in its destructor" - why? - Igor
  • @Igor so that after the destruction of the form object there is no link to its delegate at the subscriber, and there is no memory leak. As I understand it, correct if I am mistaken. - K.Oleg
  • @ K.Oleg, after the destruction of the form, all subscriptions are also destroyed - Grundy
  • @ K.Oleg The method used as a delegate does not know that it is used as a delegate, and does not store references to objects that use it as a delegate. If such links were stored, the destructor (finalizer?) Would not have volunteered. - Igor

1 answer 1

First, there is no point in unsubscribing from the events of the object being destroyed.

Secondly, if by onClose you understand a standard event , you cannot assign a null to it. And start your own event - it makes little sense.

Thirdly, starting with .NET 4.5, a new convenient tool for tracking one-time events appeared - tasks (more precisely, they appeared in 4.0, but became convenient in 4.5).

If the form is intended for a one-time display, you can do something like this:

 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(); } 

Now, in the asynchronous method, you can show the form and wait for it to close using the single await form.ShowAsync() operator.

If the same form can be shown several times - it is necessary to transfer the initialization of the tcsClosed field to the first line of the ShowAsync method, replacing the conditional operator.

No events and replies from them!


On the topic of the same question - obviously, the option -= incomeCloseEvent one handler, and the option = null written by all handlers.

If it is guaranteed that there will be only one handler, these two options are equivalent. But then it’s better to do the subscription through the assignment operator: form.onClose = incomeCloseEvent , so that it does not occur to anyone that there can be several processors.

  • Many thanks for the detailed answer! onClose meant not a standard event. - K.Oleg