4

I have a simple form with a splitviewcontainer on it, the left hand side is a menu, and the right hand side contains one or more controls.

One of the controls which can be loaded on the RHS contains a timer to refresh its data every few seconds.

If I use Controls.Clear() on the right hand side, the control is no longer displayed, but I assume it hasn't been disposed since the timer is still firing (I can see the database calls being made in logs).

My question is thus, how should I clean up my control when it has been removed from being displayed? Which event/method is called when the control is cleared?

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
KingCronus
  • 4,509
  • 1
  • 24
  • 49

3 Answers3

2

You should call the appropriate Dispose() method on the controls.

You can use an extension method to do this, see this answer from Hans Passant.

One of the controls which can be loaded on the RHS contains a timer to refresh its data every few seconds.

Now, you may have a race condition here. The timer could be due for a callback when you call your yet-to-be-created Clear() extension method. If your timer callback function is going to potentially lead to data corruption in your application, you will have to do something like this.

Timer.Stop();
Timer.Tick -= Timer_Tick(TimerCallback);
Timer.Dispose(); 

Now the other question is - Is it possible for you to just hide these controls? Is there a constraint that is preventing you from doing that?

Community
  • 1
  • 1
Bryan Crosby
  • 6,486
  • 3
  • 36
  • 55
  • Isn't just hiding controls a memory leak issue? – KingCronus Mar 16 '12 at 15:34
  • @AdamKing: What leads you to that conclusion? – Bryan Crosby Mar 16 '12 at 15:37
  • My understanding was that Hide keeps the control is memory, just doesn't display it. Is this not the case? – KingCronus Mar 16 '12 at 15:38
  • @AdamKing: It does. But when you close this form, the GC will take care of cleaning up the resources. It's not clear from your question what the lifetime of this form is, or how many times the control will be created/destroyed. In some cases it might just be easier to hide it. – Bryan Crosby Mar 16 '12 at 15:42
  • I am not planning on closing this form for considerable time, so GC won't get a chance to sort things out for me. – KingCronus Mar 20 '12 at 11:48
  • I wouldn't be concerned. It might just be easier to show/hide controls. If you have a memory problem, it will become apparent. I wouldn't prematurely optimize my code since you haven't measured it yet. – Bryan Crosby Mar 20 '12 at 15:32
1

This piece of code should work

public Form1()
{
    InitializeComponent();
    UserControl cc = new UserControl();
    Panel pp = new Panel();
    pp.Controls.Add(cc);
    pp.ControlRemoved += new ControlEventHandler(pp_ControlRemoved);
    pp.Controls.Clear();
}

void pp_ControlRemoved(object sender, ControlEventArgs e)
{
    var control = sender as MyVerySpecialControl;
    if (control != null)
    {
        //stop timers or unassign events
    }
}

I'd be glad to answer to any doubts

Luis Filipe
  • 8,488
  • 7
  • 48
  • 76
0

I would use an extension method rather than Clear(). And loop through child controls and dispose them specifically. If there are certaion controls that do not have IDispose (but should have) that cause this, then you can catch them specifically in the loop and call whatever method stops them before destroying them with a a final clear.

Wolf5370
  • 1,374
  • 11
  • 12