我发誓我知道这个问题的答案,但我忘记了。
我有这个功能。它加载位图并绘制它们。它可以快速连续调用。在大约300个位图之后,应用程序崩溃并发生System.OutOfMemoryException。
请告诉我我又做错了什么:)
private void PaintPicture()
{
string FullPath = Global.RunttimePath + EditType.FilePath;
if (File.Exists(FullPath))
{
Image i = Image.FromFile(FullPath);
//DrawImage(i, pnlPicture, pbColor.BackColor); //I disabled this so the problem is not here
i.Dispose();
//GC.Collect(); //I know I know... I should never call GC. So disabled it :)
}
else
{
//DrawImage(Properties.Resources.Fail800, pnlPicture, Color.White, true);
}
}
答案 0 :(得分:3)
根据Image.FromFile
的文档,如果位图采用未知格式,则可以获得OutOfMemoryException
。确保您的应用程序可以安全地加载您尝试使用的所有图像,并查看它是否始终在同一图像上崩溃。
如果它始终是相同的图像,那么您可以尝试以支持的像素格式(使用Photoshop或Paint.Net或其他一些免费工具)重新保存图像 - 这应该可以修复破坏您的特定图像应用
此外,在绘图逻辑周围添加一个异常处理程序,以确保应用程序在遇到错误图像时不会崩溃 - GDI +仅支持相对较少的图像格式。
要验证您是否实际耗尽内存(即,如果存在泄漏),请在应用程序运行时监视内存使用情况。如果你看到内存泄漏的迹象,你的问题可能在其他地方。
修改强>
阅读这些问题/解答,了解有关使用Image.FromStream
而不是FromFile()
的建议 - 这样做可以避免长时间锁定文件:
答案 1 :(得分:1)
这可能无法解决您的问题,但Image类实现了IDisposable。这意味着您可以将它包装在USING语句中,这会导致内部对象超出范围更快/更少的对象幸存到L2垃圾收集(它不应该在使用与调用dispose之间包装内容之间产生差异,但我们通过内存分析发现它实际上是这样做的。
if (File.Exists(FullPath))
{
using(Image i = Image.FromFile(FullPath))
{
DrawImage(i, pnlPicture, pbColor.BackColor); //I disabled this so the problem is not here
//GC.Collect(); //I know I know... I should never call GC. So disabled it :)
}
}
else
{
//DrawImage(Properties.Resources.Fail800, pnlPicture, Color.White, true);
}
}