Home > Back-end >  Is is possible for the FormClosed event to fire more than once
Is is possible for the FormClosed event to fire more than once

Time:09-29

As opposed to the FormClosing event, which can be fired multiple times in a slow-to-respond app with a user jumping on the close button repeatedly.

Is it possible for the FormClosed event to fire multiple times?

Eg, is the following try/catch necessary?

private void MyForm_FormClosed(object sender, FormClosedEventArgs e)
{
    // Dispose the CancellationTokenSource
    // Is it possible for this to be fire more than once!?
    try
    {
        cts.Dispose();
        cts = null;
    }
    catch { }
}

CodePudding user response:

Well, it is always possible to add the same event multiple times to the same handler, in which case it would be called multiple times!

But outside of, this I can't find any documentation which guarantees that it will only be called once, but looking at the WInform lifecycle https://docs.microsoft.com/en-us/dotnet/desktop/winforms/order-of-events-in-windows-forms?view=netframeworkdesktop-4.8

I would say that you can be pretty sure that it should be only called once.

However, I would still employ safe coding practices and keep the try catch, or use the null conditional operator.

If you don't catch an exception which, such as this, is harmless, and/or have (or later add) a global exception handler then it will catch and handle such things which could be totally unnecessary and clog up your logs files with what is effectively junk. (I have seen this too often)

CodePudding user response:

Calling cts.Dispose(); by itself would be absolutely fine, setting it to null is redundant and doesn't help the garbage collector, and try catch is overkill.

A CancellationTokenSource.Dispose just takes care of a timer and a handle to a kernel event (ManualResetEvent), both are cleaned up in a thread safe manner and both implementation will handle being called twice and are fault tolerant.

Depending on how you instantiated the CancellationTokenSource you could also use the null conditional operator for good measure.

Example

private void MyForm_FormClosed(object sender, FormClosedEventArgs e)
  => cts?.Dispose();

Its worth noting CancellationTokenSource checks if it has been previously disposed anyway

protected virtual void Dispose(bool disposing)
{
   if (disposing && !_disposed)
   {
      ...

As to whether a Form OnClose event can be called twice, I haven't deviled into the code, yet my assumption is that it will work on the message pump, and unless you call the event yourself it will only be called once. Even if otherwise, you are covered anyway

  • Related