我正在尝试从数据库加载一组图像,并为一组按钮设置背景图像。
我似乎"内存耗尽"加载按钮的背景图像时。我用图片框(而不是按钮)尝试了这种方法,它可以工作。
我做错了什么?
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++;
}
}
答案 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);
并且有效。