Hello,
I've got this memory leak, could you guys give an explanation/workaround? I've made the simplest test case (see below), factors for the bug to occur (that I already discovered):
- it's an MDI form situation with parent & child
- the child is maximized (the menu items are added into one menubar)
- the menu item provided by the client is a menu button
- a textbox is on the child form
TestMdiParent.cs
TestMdiChild.cs
TestMdiChild.Designer.cs
If you call the parent MDI form and let it run a bit you should see the GDI objects increase by one each second and never get released.
If you know a solution/workaround, thanks a lot
Frederik
I've got this memory leak, could you guys give an explanation/workaround? I've made the simplest test case (see below), factors for the bug to occur (that I already discovered):
- it's an MDI form situation with parent & child
- the child is maximized (the menu items are added into one menubar)
- the menu item provided by the client is a menu button
- a textbox is on the child form
TestMdiParent.cs
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using Telerik.WinControls.UI;namespace MenuMemoryLeak{ public partial class TestMdiParent : Telerik.WinControls.UI.RadForm { public TestMdiParent() { InitializeComponent(); } //NOTE this stuff with the backgroundworker is just to repeatedly close/open the form, I know it's not fully correct but the bug occurs nevertheless BackgroundWorker myWorker = new BackgroundWorker() { WorkerReportsProgress = true, WorkerSupportsCancellation = false }; TestMdiChild myMdiChild; private void TestMdiParent_Shown(object sender, EventArgs e) { myWorker.DoWork += delegate { int count = 0; while(true) { ++count; myWorker.ReportProgress(count); System.Threading.Thread.Sleep(1000); } }; myWorker.ProgressChanged += delegate { if(myMdiChild != null) { myMdiChild.Close(); System.GC.Collect(); } myMdiChild = new TestMdiChild() { MdiParent = this }; myMdiChild.Show(); }; myWorker.RunWorkerAsync(); } }}
TestMdiParent.Designer.csnamespace MenuMemoryLeak{ partial class TestMdiParent { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.testMenuItem = new Telerik.WinControls.UI.RadMenuItem(); this.testParentMenu = new Telerik.WinControls.UI.RadMenu(); ((System.ComponentModel.ISupportInitialize)(this)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.testParentMenu)).BeginInit(); this.SuspendLayout(); // // testMenuItem // this.testMenuItem.Name = "testMenuItem"; this.testMenuItem.Text = "Parent"; // // TestMdiParent // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(902, 523); // // testParentMenu // this.testParentMenu.Items.AddRange(new Telerik.WinControls.RadItem[] { this.testMenuItem}); this.testParentMenu.Location = new System.Drawing.Point(0, 0); this.testParentMenu.Name = "testParentMenu"; this.testParentMenu.Size = new System.Drawing.Size(902, 24); this.testParentMenu.TabIndex = 1; this.testParentMenu.Text = "radMenu1"; this.Controls.Add(this.testParentMenu); this.IsMdiContainer = true; this.Name = "TestMdiParent"; // // // this.RootElement.ApplyShapeToControl = true; this.Text = "TestMdiParent"; this.ThemeName = "ControlDefault"; this.Shown += new System.EventHandler(this.TestMdiParent_Shown); ((System.ComponentModel.ISupportInitialize)(this.testParentMenu)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private Telerik.WinControls.UI.RadMenuItem testMenuItem; private Telerik.WinControls.UI.RadMenu testParentMenu; }}TestMdiChild.cs
using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using Telerik.WinControls;namespace MenuMemoryLeak{ public partial class TestMdiChild : Telerik.WinControls.UI.RadForm { public TestMdiChild() { InitializeComponent(); //NOTE required for bug to occur this.WindowState = FormWindowState.Maximized; } }}TestMdiChild.Designer.cs
namespace MenuMemoryLeak{ partial class TestMdiChild { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.testMenuButtonItem = new Telerik.WinControls.UI.RadMenuButtonItem(); this.testChildMenu = new Telerik.WinControls.UI.RadMenu(); this.testTextBox = new Telerik.WinControls.UI.RadTextBox(); ((System.ComponentModel.ISupportInitialize)(this.testChildMenu)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.testTextBox)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this)).BeginInit(); this.SuspendLayout(); // // testMenuButtonItem // this.testMenuButtonItem.Name = "testMenuButtonItem"; this.testMenuButtonItem.Text = "Child"; // // testChildMenu // this.testChildMenu.AllowMerge = false; this.testChildMenu.IsMainMenu = false; this.testChildMenu.Items.AddRange(new Telerik.WinControls.RadItem[] { this.testMenuButtonItem}); this.testChildMenu.Location = new System.Drawing.Point(0, 0); this.testChildMenu.Name = "testChildMenu"; this.testChildMenu.Size = new System.Drawing.Size(467, 24); this.testChildMenu.TabIndex = 2; this.testChildMenu.Text = "radMenu1"; // // testTextBox // this.testTextBox.Location = new System.Drawing.Point(22, 23); this.testTextBox.Name = "testTextBox"; this.testTextBox.Size = new System.Drawing.Size(100, 20); this.testTextBox.TabIndex = 1; this.testTextBox.TabStop = false; this.testTextBox.Text = "test"; // // TestMdiChild // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(467, 268); this.Controls.Add(this.testChildMenu); this.Controls.Add(this.testTextBox); this.Name = "TestMdiChild"; // // // this.RootElement.ApplyShapeToControl = true; this.Text = "TestMdiChild"; this.ThemeName = "ControlDefault"; ((System.ComponentModel.ISupportInitialize)(this.testChildMenu)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.testTextBox)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this)).EndInit(); this.ResumeLayout(false); this.PerformLayout(); } #endregion private Telerik.WinControls.UI.RadMenuButtonItem testMenuButtonItem; private Telerik.WinControls.UI.RadMenu testChildMenu; private Telerik.WinControls.UI.RadTextBox testTextBox; }}If you call the parent MDI form and let it run a bit you should see the GDI objects increase by one each second and never get released.
If you know a solution/workaround, thanks a lot
Frederik