所以我目前正在开发一个工作/工作得非常好的图像缩放器,但有一个例外,当我一次处理过多的图像时,它给了我一个OutOfMemoryException。
因此,为了解决这个问题,我已将方法包装在using语句中,以便正确处理Bitmaps。
但是我注意到如果我在using语句中返回我的Bitmap,我会得到这个" ArgumentException未处理"消息
这是我的ImageResize方法:
public Bitmap ResizeImage(MemoryStream ms, Size size)
{
if (comboBox2.Text == "Pixel")
{
using (Bitmap img = new Bitmap(new Bitmap(ms, true), size.Width, size.Height))
{
var original = new Bitmap(ms, true);
Graphics graphic = Graphics.FromImage(img);
//IRRELEVANT CODE.....
return img;
}
}
else
{
return null;
}
在这里,当我尝试将图像保存在ImageResize方法之外时:
private void button1_Click(object sender, EventArgs e)
{
//IRRELEVANT CODE ...
img = ResizeImage(memory, new Size(getX(), getY()));
//IRRELEVANT CODE ...
img.Save(outputFileName, codec, encoderParams); //<-Exception occurs here
}
当我删除using语句时,一切都运行得很好,但是我必须使用using块来处理Bitmap,以防止内存泄漏。 此外,当我将图像保存在using语句中时,它也可以正常工作,但在我的情况下,这不是解决方案。
我做错了什么?对我而言,似乎没有正确返回Bitmap。
我感谢任何帮助和提前感谢 Ravand
答案 0 :(得分:5)
你把你的使用放在了错误的地方。在使用块结束(包括从其返回)之后,布置由块控制的对象。访问配置的位图是一个错误。
你的使用需要在这里:
private void button1_Click(object sender, EventArgs e)
{
//IRRELEVANT CODE ...
using(img = ResizeImage(memory, new Size(getX(), getY())))
{
//IRRELEVANT CODE ...
img.Save(outputFileName, codec, encoderParams);
}
}
答案 1 :(得分:0)
好吧我终于解决了内存泄漏的问题,结果发现我确实正在释放/处理图像,但它没有做得足够快,导致这个outOufMemoryException,因为你正在处理很多非常大的图像其他。我尝试将所有内容都设置为多线程,并且总是在等待WorkingSet变小而没有成功。
原来它比我想的更容易,我所要做的就是在调整大小的方法结束时把它放在:
GC.Collect();
GC.WaitForPendingFinalizers();
System.Threading.Thread.SpinWait(5000);
这似乎有助于调整大小为10-20mb的大尺寸图像以及10000x10000的分辨率。有人可以解释为什么SpinWait会帮助但不能正常线程睡眠?每当我尝试睡觉时,它似乎也会释放记忆。