加载按钮阵列的背景图像时内存不足

时间:2015-06-23 20:04:14

标签: c#

我正在尝试从数据库加载一组图像,并为一组按钮设置背景图像。

我似乎"内存耗尽"加载按钮的背景图像时。我用图片框(而不是按钮)尝试了这种方法,它可以工作。

我做错了什么?

Button[] pb = { pictureButton1, pictureButton2, pictureButton3, pictureButton4, pictureButton5,
        pictureButton6, pictureButton7, pictureButton8, pictureButton9, pictureButton10, pictureButton11, pictureButton12, pictureButton13,
        pictureButton14, pictureButton15, pictureButton16, pictureButton17, pictureButton18, pictureButton19, pictureButton20, pictureButton21 };


        using (MySqlDataReader dr = cmdDataBase.ExecuteReader())
        {
            int i = 0;
            while (dr.Read())
            {
                using (MemoryStream stream = new MemoryStream())
                {
                    if (dr["ITEM_Picture"] != DBNull.Value)
                    {
                        byte[] image = (byte[])dr["ITEM_Picture"];
                        stream.Write(image, 0, image.Length);
                        Bitmap bitmap = new Bitmap(stream);
                        if (i >= 21)
                        {
                            return;
                        }
                        pb[i].BackgroundImage = (bitmap);

                    }
                }

                i++;

            }
        }

2 个答案:

答案 0 :(得分:3)

您有一些内存泄漏:

该行

pb[i].BackgroundImage = (bitmap);

正在制作bitmap的深层副本,我不确定你想要的是什么。在任何一种情况下,你当前的实现都是创建一个位图,复制它(这可能是资源密集型的,应该避免 - 你要分配一些东西,然后复制它只是为了方便为新位图设置一个本地标签),以及永远不会释放创建当前bitmap实例时分配的内存。

试试这个:

using(var bitmap = new Bitmap(stream))
{
    if (i >= pb.Length)
    {
        return;
    }
    pb[i].BackgroundImage = (bitmap);
}

如果那不是问题:抛出异常是哪一行?

另外,你真的不应该构建像pb这样的数组。尝试遍历父项的Controls属性并检查PictureButtons。拥有这样的硬编码数组意味着当任何人添加,删除或重命名控件时,必须更新加载代码。此外,我希望您的数据库查询正确排序按钮,而不是依赖于插入顺序。

另外,我不得不问:如果数据库中的行数PictureButton不同,会发生什么?这是一个非常脆弱的设计。 (显然它不会崩溃,但图像将被忽略,或者按钮将留空,或者更糟糕的是,显示上次刷新时加载的任何图像 - 陈旧数据)。

答案 1 :(得分:0)

我刚改变了:

pb[i].BackgroundImage = (bitmap);

pb[i].Image = (bitmap);

并且有效。