简体   繁体   中英

How to determine whether a C# control is being unloaded?

In my C# Windows Forms application, I have a user control that contains other controls and does its own logic. One of them is a delayed call (Timer-invoked) that does certain things after the user has finished a keyboard input (live filter text). It accesses the other controls for this, one of them is that text input control. This method is invoked 500 ms after the last input event.

Now I have a problem when the delayed call is running while the application is terminating. When I enter some text, then wait about 500 ms (it seems to work every time) and then press Alt+F4 to close the window, the application throws a NullReferenceException while trying to access the text input control. This doesn't happen when I close the window immediately after the last input or a second or more after.

It seems that the control is being disposed or something and its methods cannot access the child controls anymore. So, when the control is being put in that state (by whomever and whatever that state exaclty is), those timer need to be stopped first so that the controls can be safely disposed.

I have already tried to stop the timer in the OnHandleDestroyed method (overridden) and at the beginning of the Designer-generated Dispose method. Nothing helped.

This procedure works fine in regular Forms when stopping the timers in the overridden OnFormClosed method, before calling base.OnFormClosed(). I just cannot find a suitable event in a user control.

Try this in your UserControl:

bool isDisposed;
protected override void Dispose(bool disposeManaged)
{
    if(!isDisposed)
    {
        if(disposeManaged)
        {
            //Dispose your timer here
        }
        isDisposed = true;
    }
}

Another possibility is that one of your UI classes doesn't do its cleanup. Eg. it registers itself for an event but doesn't deregister when it's manually disposed. It is never collected by the GC and when the event is fired for the next time, it tries to access some members that were set to null during the Dispose(...) call before.

Another possibility is that you have a more complex race condition within your code but it's hard to say from here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM