aferia
asked on
Proper way to dispose dynamically created controls.
Hi,
I have adopted a technique in VB.NET that allows me to design a group control with several children controls as a template that can be cloned as needed. I instantiate the template form that holds the group control, then insert the group control into my application's form. This is leaking memory and I do not know how to get rid of the leak. What is the proper way to dispose of the template form and group control?
I have included a simplified sample of what the source code looks like.
Public Class MainForm
Private templateObject as object
Public Sub CreateNewGroupBoxTemplate( )
Dim tempTemplateForm as new FTemplateForm
templateObject = tempTemplateForm.grpTempla teGroupCon trol
me.controls.add(templateOb ject )
tempTemplateForm .Dispose()
End sub
Public Sub DeleteTemplate()
me.controls.remove(templat eObject )
templateObject.Dipose()
End Sub
End Class
I have adopted a technique in VB.NET that allows me to design a group control with several children controls as a template that can be cloned as needed. I instantiate the template form that holds the group control, then insert the group control into my application's form. This is leaking memory and I do not know how to get rid of the leak. What is the proper way to dispose of the template form and group control?
I have included a simplified sample of what the source code looks like.
Public Class MainForm
Private templateObject as object
Public Sub CreateNewGroupBoxTemplate(
Dim tempTemplateForm as new FTemplateForm
templateObject = tempTemplateForm.grpTempla
me.controls.add(templateOb
tempTemplateForm .Dispose()
End sub
Public Sub DeleteTemplate()
me.controls.remove(templat
templateObject.Dipose()
End Sub
End Class
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
*There is a difference, though, between trusting .Net and using an inefficient design. We can't tell from your posted code if you are doing something in a way that might be better achieved with a different approach... ;)
This I agree with:
...this I do not:
If an item has a Dispose method available, then it probably does so for a reason. I think the calling of Dispose above is appropriate assuming the code above is adding objects which inherit from the Control class--which does use unmanaged resources (e.g. window handles).
This I'm not sure I 100% agree with, but I kind of understand the intent:
Memory isn't released by .NET immediately because garbage collection is an expensive operation. For this reason I strongly discourage the use of GC.Collect. It is very rare that you would ever need to call this method, and if you put this call in the wrong place in your code (i.e. a place called frequently), you can assuredly bring your application to a halt.
You should only be *implementing* ... Dispose if you are using unmanaged resources
...this I do not:
You should only be ... calling Dispose if you are using unmanaged resources
If an item has a Dispose method available, then it probably does so for a reason. I think the calling of Dispose above is appropriate assuming the code above is adding objects which inherit from the Control class--which does use unmanaged resources (e.g. window handles).
This I'm not sure I 100% agree with, but I kind of understand the intent:
Usually it's just .Net being greedy and not immediately releasing memory since it may need it again in the near future.
Memory isn't released by .NET immediately because garbage collection is an expensive operation. For this reason I strongly discourage the use of GC.Collect. It is very rare that you would ever need to call this method, and if you put this call in the wrong place in your code (i.e. a place called frequently), you can assuredly bring your application to a halt.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks everyone!
From what I understand a container control should dispose all of its children when all reference variables for that control fall out of scope or are set to nothing. Does .NET's GC check all the reference variables in my program to determine what needs to be deallocated? Doesn't the GC call Dispose on the variables that have lost all references? So in theory, shouldn't I see the memory footprint going down if I am 100% sure that I have removed all references to a control and called GC.Collect() (even without calling dispose)?
Also, manually calling dispose(), but not clearing out the reference to nothing (assuming that it will stay in scope) seems to have no effect on the memory allocation.
I have researched the subject on Google, but I have not been able to find a single comprehensive source on precisely how to answer these questions, please help!
From what I understand a container control should dispose all of its children when all reference variables for that control fall out of scope or are set to nothing. Does .NET's GC check all the reference variables in my program to determine what needs to be deallocated? Doesn't the GC call Dispose on the variables that have lost all references? So in theory, shouldn't I see the memory footprint going down if I am 100% sure that I have removed all references to a control and called GC.Collect() (even without calling dispose)?
Also, manually calling dispose(), but not clearing out the reference to nothing (assuming that it will stay in scope) seems to have no effect on the memory allocation.
I have researched the subject on Google, but I have not been able to find a single comprehensive source on precisely how to answer these questions, please help!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you very much for your help! I wish I has more points to distribute!
http://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.90).aspx
However, Garbage Collection (http://msdn.microsoft.com/en-us/library/0xy59wtx(v=vs.90).aspx) is the general term for what you want to do. And...it's best to let the system perform its own garbage collection. You could possibly induce the collection by calling GC.Collect() (rather than that Dispose() you have in your code), but again, it's best to let the system do that for you.
Try using GC.Collect() and see what happens.