使用picturebox处理winforms usercontrol - 当前泄漏的内存

时间:2015-06-05 09:57:50

标签: c# winforms memory-leaks user-controls

首先,我已经阅读了多个问题和答案类似,但与我遇到的问题不一样 - 我相信这不是重复。

简而言之,我的应用程序正在泄漏内存。

我有一个Flowpanel包含UserControl的多个实例,其中包含两个Picturebox控件和一个Label以及一个ToolTip

我的Usercontrol是不可变的,每个实例都包含一些状态信息和一些来自Properties.Resources对象的图像。

当状态改变时,我从flowpanel中删除usercontrol并将其替换为新的。这导致我的应用程序的内存使用量不断增加。

我怀疑我没有正确处理用户控件或图片框 - 但不确定在哪里?

用户控件:

public partial class ucArrayStatus : UserControl
{
    private ToolTip toolTip = new ToolTip();
    public ucArrayStatus(string arrayDesc, ArrayStatus status /*this is an enum*/)
    {
        InitializeComponent();
        labArrayDesc.Text = arrayDesc;
        labStatus.Text = status.ToString();
        toolTip.SetToolTip(this, status.ToString());
        if (status == ArrayStatus.Complete)
        {
            //pbStatusIcon is a PictureBox control
            pbStatusIcon.Image = Properties.Resources.complete;
            pbStatusIcon.SizeMode = PictureBoxSizeMode.Zoom;
        }
        else
        {
            pbStatusIcon.Image = Properties.Resources.working;
            pbStatusIcon.SizeMode = PictureBoxSizeMode.CenterImage;
        }
    }
}

我是否需要在此类中添加Dispose()以显式处理Image?

创建和删除用户控件:

public class ArrayUIHandler
{
    //store each usercontrol in a specific order indexed by this dictionary
    private Dictionary<int, ucArrayStatus> configToControl = new Dictionary<int, ucArrayStatus>();
    private void ApplyStatusItem(int index, ArrayStatus status)
    {
        var item = new ucArrayStatus(CreateArrayStatusDescription(), status);
        container.Invoke((Action)(() =>
        {
            lock (accessLock)
            {
                if (!configToControl.ContainsKey(index))
                {
                    Logger.Log("UpdateStatus(): Unable to find array: {0}. ControlCount: {1}", index, 
                                container.Controls.Count);
                }
                var c = configToControl[index]; //extract from dictionary
                var controlIndex = container.Controls.IndexOf(c); //retrieve from flowpanel           

                container.Controls.Remove(c); //remove from flowpanel controlcollection
                configToControl.Remove(index); //remove from dictionary
//dispose (not sure if more is needed here, or to implement dispose in the usercontrol??)
                c.Dispose();
                c = null; //explicitly set to null - not sure if needed?
                container.Controls.Add(item); //add new usercontrol to flowpanel
                container.Controls.SetChildIndex(item, controlIndex); //set index position
                configToControl.Add(index, item); //add to dictionary

            }
        }));
    }
}

我发现的大多数帖子都会因为从文件或字节数组等加载图像而出现问题,这在我使用Resources对象时是否适用?

EDIT1

向用户控件添加Dispose()方法似乎无法解决问题。

代码:

protected override void Dispose(bool disposing)
{
    if (disposing && (pbStatusIcon.Image != null))
    {
        pbStatusIcon.Image.Dispose();
        pbStatusIcon.Image = null;
        pbStatusIcon.Dispose();

    }
    if (disposing && (components != null))
    {
        components.Dispose();
    }
    base.Dispose(disposing);
}

2 个答案:

答案 0 :(得分:0)

我遇到的问题与你的问题相似,我搞砸了几件事,发现这个问题有效。

处理图像(我将我的设置作为变量)

pictureBox1Image.Dispose();

pictureBox1.BackgroundImage = null;

我建议先尝试一下,看看是否有帮助。

答案 1 :(得分:0)

检查您拥有的所有Disposable对象,并为所有这些对象调用Dispose。我可以看到你有一次性使用的工具提示。确保丢弃所有一次性实例。这是一般的最佳实践规则。