我想我的记忆回来了!我如何可以真正处理一个控制?
题
我有一个应用程序,我提出,创造了大量的窗口控制(按钮和标签等)。他们都是由动态地通过功能。这问题我有的是,当我删除了控制和处置他们,他们不是从存储器。
void loadALoadOfStuff()
{
while(tabControlToClear.Controls.Count > 0)
tabControlToClear.Controls[0].Dispose();
//I even put in:
GC.Collect();
GC.WaitForPendingFinalizers();
foreach(String pagename in globalList)
tabControlToClear.Controls.Add(MakeATab(pagename));
}
TabPage MakeATab(string tabText)
{
TabPage newT = new MakeATab();
newT.Text = tabText;
//Fill page with controls with methods like this
return newT;
}
现在由于某些原因,这仅仅是不给我我的记忆回来的,所以当该进程的运行5次,我结束了内存侵犯。我是新来的对象和控制的处置,但期待通过的庞大净仍然没有给我任何迹象表明,所以如果你有一个想法,我很感激听到它。
更新:我一直在看着用户对象的创造和毁灭的(任务管理器),并注意到创建一个标签页,添加一个处理程序击,添加一个小组,加2个按钮都有点击处理程序、工具提示和backimages(我觉得这是问题)。该应用程序说,它创建了8个新项目,但是,当我运行,通过我处理,我只删除4从存储器。我已经试图要删除该事件的处理程序,但它似乎没有差别。
解决!!!因为我是增加新的项目,面板,我是路过的他们一个提示(愚蠢的,但我的学习).对于任何其他人具有同样的问题,(由于意见和方向,从人如下。我发现为了使控制真正处置(为我意识到我多么错误地把它的)是:
1:如果你有一个工具,确保它ACCESSABLE!不做什么,我没有!例如:
这是错的!
TabPage MakeATab(string tabText)
{
TabPage newT = new MakeATab();
ToolTip myTip = new ToolTip();
newT.Text = tabText;
//Fill page with controls with methods like this
myTip.SetToolTip(newT, "Something to say");
return newT;
}
如果你这么做,你将失去所指的提示,并作为提示是不是一个孩子的目的是连接(而,该工具提示,使得一个强大的参照控制),然后甚至如果你摧毁的控制,提示你不能访问保持目活着。
2:任何事情之前,呼提示。RemoveAll().这消除了所有这关系到控制。注意,如果使用这一尖端对于其他的控制,他们只是失去了他们的刀尖头。
3:删除任何内部控制从基地的控制。ControlCollection(如果他们使用不受管理的记忆中,我猜。我这样做是因为它使我应用程序的工作所以...)
4:删除任何定义事件的处理程序。
5:最后处置的对象。我做了一个快速递归访问功能,做得相当好。
private void RecursiveDispose(Control toDispose)
{
while (toDispose.Controls.Count > 0)
RecursiveDispose(toDispose.Controls[0]);
if (toDispose.BackgroundImage != null)
BackgroundImage = null;
if (toDispose.GetType() == typeof(Button))
toDispose.Click -= [Your Event];
else if (toDispose.GetType() == typeof(TabPage))
toDispose.DoubleClick -= [Your Event];
else if (toDispose.GetType() == typeof(Label))
toDispose.MouseMove -= [Your Event];
toDispose.Dispose();
}
这是非常粗和有可能是一个更好的方式这样做,但除非有人可以过来,这将必须做的。谢谢你的帮助每一个人。你也许只是救了我的整个项目。
解决方案
您需要也明确了引用。
while(tabControlToClear.Controls.Count > 0)
{
var tabPage = tabControlToClear.Controls[0];
tabControlToClear.Controls.RemoveAt(0);
tabPage.Dispose();
// Clear out events.
foreach (EventHandler subscriber in tabPage.Click.GetInvocationList())
{
tabPage.Click -= subscriber;
}
}
其他提示
在此代码块你调用Dispose但不移除所述参考:
while(tabControlToClear.Controls.Count > 0)
tabControlToClear.Controls[0].Dispose();
您需要删除的控制来控制(加上你可能在Controls集合中的任何注册的事件处理以及其他任何引用)的所有引用才有资格进行垃圾回收。
void loadALoadOfStuff()
{
while(tabControlToClear.Controls.Count > 0)
tabControlToClear.Controls[0].Dispose();
//I even put in:
GC.Collect();
GC.WaitForPendingFinalizers();
foreach(String pagename in globalList)
tabControlToClear.Controls.Add(MakeATab(pagename));
}
在我看来,你是重新分配在您的测试方法结束时,所有的选项卡的情况下,所以显然是不首先处置他们的利益。跳到最后两行,看看是否有帮助。