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

本文关键字:图像 内存不足 背景 按钮 阵列 加载 | 更新日期: 2023-09-27 17:59:10

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

加载按钮的背景图像时,我似乎"内存不足"。我用图片框(而不是按钮)尝试了这种方法,它很有效。

我做错了什么?

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

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

您有一些内存泄漏:

线路

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的数量与数据库中的行数不同,会发生什么?这是一个非常脆弱的设计。(很明显,它不会崩溃,但图像会被忽略,或者按钮会留空,或者更糟的是,显示上次刷新时加载的任何图像——过时的数据)。

我刚刚更改了:

pb[i].BackgroundImage = (bitmap);

pb[i].Image = (bitmap);

它奏效了。