I've noticed that I have this huge memory leak.My app relies heavily on infragistics ui components, and our code createsAnd destroys many UserControls that comprise mostly of UltraTextEditors.After some research I found that the constructor is not called on ANY control that contains an UltraTextEditor (and probably other editors as well).
This seemed so weird to me that I started a new project, that contains a main form, and a single user control, which in turn contains a single UltraTextEditor. I added a destructor to this control, and set it to print a message to the debug console.To the main control I added a single button that creates my user control and looses reference to it, and then a call to GC.Collect();.
If the control contains the UltraTextEditor, the descructor is never called, if I remove the line with "this.controls.add(ultraTextEditor1); " the destructor is called as expected.Why does this happen? Is there some setting I need to know of somewhere that prevents my control from being GCed? Does the UltraTextEditor save a reference to the parent class in some static place that never gets out of scope?
I'm not sure I completely follow this. Are you disposing the UserControl too? When you add the UltraTextEditor to the UserControl's Controls collection, the UserControl itself will hold onto the reference to the editor until the UserControl itself is disposed, which is why you're are seeing everything work when you remove 'this.controls.add...".
-Matt
i'll add my test's code example to clarify the test i'm running:
public class Test : UserControl { public Test() { Debug.WriteLine("Creating control"); this.Controls.Add(new UltraTextEditor()); //this.Controls.Add(new TextBox()); } ~Test() { Debug.WriteLine("Test destructor called on user control"); } } static class Program { private static void CreateTest() { Test test = new Test(); GC.Collect(); //request GC cycle } [STAThread] static void Main() { for (int i=0; i<10; i++) CreateTest(); Debug.WriteLine("Leaving test"); } }
this test outputs:
Creating controlCreating controlCreating controlCreating controlCreating controlCreating controlCreating controlCreating controlCreating controlCreating controlLeaving test
if we comment out the infragistics control and uncomment the TextBox we get:
Creating controlCreating controlCreating controlTest destructor called on user controlTest destructor called on user controlCreating controlTest destructor called on user controlCreating controlTest destructor called on user controlCreating controlTest destructor called on user controlCreating controlTest destructor called on user controlCreating controlTest destructor called on user controlCreating controlTest destructor called on user controlCreating controlLeaving test
-Yossi
The usual way this happens is that the call to Dispose (from the IDisposable interface) is supposed to occure when the object gets GCed.
if the interface is implemented on an object that is not a "Control" or "UserControl", then a call has to be made from the destructor to MyObject.Dispose();
For Objects that inherit from "Control", the Control finalizer includes a call to .Dispose()
i.e. if instead of an infragistics control i add a regular windows TextBox, the test i mentiond runs as it should, since the TextBox gets GCed, and the finalizer calls the controls .Dispose() method, after the TextBox is collected, my parent control can be collected as well.
What i suspect is that for some reason Infragistics Controls , or perheps some Controls are somehow still reachable and so they never get GCed, and the Dispose method is never called by the destructor.
-Yossi.