我想要我的记忆!我如何才能真正配置控件? [英] I want my memory back! How can I truly dispose a control?

查看:96
本文介绍了我想要我的记忆!我如何才能真正配置控件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个正在制作的应用程序,它创建了大量的Windows控件(按钮和标签等).它们都是通过功能动态创建的.我遇到的问题是,当我删除控件并处理它们时,它们不会从内存中删除.

I have an application I am making that creates a large number of windows controls (buttons and labels etc). They are all being made dynamically through functions. The problem I'm having is, when I remove the controls and dispose them, they are not removed from memory.

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次时,我最终遇到内存不足冲突.我是反对和控制处置的新手,但通过庞大的网络查看仍没有任何迹象,因此,如果您有任何想法,我将不胜感激.

Now for some reason, this just ain't giving me my memory back, so when the process runs 5 times, I end up with an out of memory violation. I am new to object and control disposal but looking through the vast net still hasn't given me any indications, so if any of you have an idea, I'd be grateful to hear it.

更新:我一直在观察用户对象的创建和销毁(任务管理器),并注意到我创建了一个标签页,添加了一个单击处理程序,添加了一个面板,并添加了两个带有单击处理程序,工具提示和背景图像的按钮(我认为这就是问题所在).该应用程序说它创建了8个新项目,但是当我执行处置时,我只从内存中删除了4个项目.我一直在尝试删除事件处理程序,但似乎没有什么作用.

UPDATE: I've been watching the user objects creation and destruction (taskmanager) and noticed I create a tab page, add a click handler, add a panel, add 2 buttons both with click handlers, tooltips and backimages (I think this is where the problem is). The app says it creates 8 new items, but when I run through my dispose, I only remove 4 from memory. I've been trying to remove the event handlers, but it seems to make no difference.

已解决!!!当我在面板上添加新项目时,我在传递给他们一个工具提示(愚蠢,但我正在学习).对于其他有相同问题的人,(感谢下面的人的评论和指示.我发现,为了真正地处置控件(我意识到我的说法不正确)是

RESOLVED!!! As I was adding new items to the panel, I was passing them a tooltip (stupid, but I'm learning). For anyone else who has the same problem, (thanks to comments and directions from people below. I discovered in order to make a control truly dispose (as I realise I so incorrectly put it) is:

1:如果您有工具提示,请确保可以访问!不要做我所做的事情!例如:

1: IF YOU HAVE A TOOL TIP, MAKE SURE IT'S ACCESSABLE! DO NOT DO WHAT I DID! E.g:

这是错误的!

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

如果执行此操作,则将丢失指向工具提示的指针,并且由于工具提示不是它所连接的对象的子代(相反,工具提示强烈引用了控件),即使您销毁了该提示,控件,您无法访问的工具提示使对象保持活动状态.

If you do this, you will lose the pointer to the tooltip, and as the tooltip is not a child of the object it's connected to (rather, the tooltip makes a strong reference to the control), then even if you destroy the control, the tooltip that you can't access keeps the object alive.

2:在进行任何操作之前,请先调用toolTip.RemoveAll().这消除了与控件的所有联系.请注意,如果你使用这个技巧对于其他控件,他们刚刚失去了他们的工具提示.

2: Before anything, call toolTip.RemoveAll(). This removes all it's ties to controls. Note, if you were using this tip for other controls, they just lost their tool tip.

3:从基本control.ControlCollection中删除所有内部控件(如果它们使用非托管内存,我想.我正在这样做是因为它使我的应用程序正常工作了...)

3: Remove any internal controls from the base control.ControlCollection (if they use non managed memory, I guess. I'm doing it cause it's making my app work so...)

4:删除所有自定义事件处理程序.

4: remove any custom event handlers.

5:最后,处置该物体.我做了一个快速递归功能,效果很好.

5: finally, dispose the object. I made a quick recursing function that does it quite well.

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

这是非常粗糙的,并且可能有更好的方法,但是除非有人能提出,否则必须这样做.谢谢大家的帮助.您可能只是保存了我的整个项目.

This is extremely crude and there's probably a much better way of doing it, but unless someone can come up with it, this will have to do. Thanks for your help everyone. You might just have saved my entire project.

推荐答案

您还需要清除引用.

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

这篇关于我想要我的记忆!我如何才能真正配置控件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆