我有一个应用程序,我提出,创造了大量的窗口控制(按钮和标签等)。他们都是由动态地通过功能。这问题我有的是,当我删除了控制和处置他们,他们不是从存储器。

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));
}

在我看来,你是重新分配在您的测试方法结束时,所有的选项卡的情况下,所以显然是不首先处置他们的利益。跳到最后两行,看看是否有帮助。

有很多大问题的答案迄今为止,提到一个可能的理由的对象,不是被释放,他们是所有东西值得检查。

但是当我得到这种类型的问题,我用一个 存储器的探查 帮助追踪的参考(s)的目的,我最后一次看看记忆分析器, 蚂蚁内存分析器 (从 展鹏)是最好的之一。(他们做一个14天的尾巴,是多长到足以进行调查的一个类似的问题。)

这是其中一个原因,弱事件模式是使用,但是这将是一个 全新的问题.

(一生的对象当你动态修改的一个UI是一个雷区,以及完成任务管理器,以检查你的代码是按预期工作)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top