在我用C#编码的图像查看器中添加“下一个”和“上一个”导航选项时,当我按下“下一步”约20次时,Visual Studio会告诉我该进程内存不足。它在任何具有许多文件夹的文件夹中执行此操作,即使它们的图像文件大小都很小
我明白了:
未处理的类型' System.OutOfMemoryException'发生在System.Drawing.dll中的附加信息:内存不足。
这是我正在使用的代码
private void next_Click(object sender, EventArgs e)
{
string[] foldernm = Directory.GetFiles(Path.GetDirectoryName(lfoto_file.FileName));
_pictureIndex++;
if (_pictureIndex >= foldernm.Length)
{
_pictureIndex = 0;
}
ibread_img.Image.Dispose();
ibread_img.Image = Image.FromFile(foldernm[_pictureIndex]);
}
现在你可以看到,我有ibread_img.Image.Dispose();
因为我已经搜索了这个,其他人说要使用它,但它不起作用,我仍然遇到同样的问题,一个休息 - 点确认代码正在运行所以我很困惑为什么它仍然耗尽内存。我骑自行车的图像并不大。我已经尝试了我能找到的所有内容,包括清空以前加载的图像,手动调用垃圾收集器,似乎没有任何工作。我不是C#中的佼佼者,因此代码中可能存在可怕的错误或缺陷,但我不知道如何解决这个问题?
答案 0 :(得分:1)
您可以采取一些措施来改善观众。首先,您每次都在重新创建图像文件列表;你每次加载所有这些只是为了访问下一个,你不必创建一个图像,以显示它。
// class level vars
int picIndex = 0;
IEnumerable<string> files;
int filesCount;
string picPath;
static string[] imgExts = {".png", ".jpg",".gif"};
由于您提到了“下一个”和“上一个”按钮,因此您必须在其他位置具有几乎相同的代码这将消除重复,下一步:
ShowImage(picIndex);
picIndex+=1;
if (picIndex >= filesCount)
picIndex = 0;
然后是一种显示所需图像的方法:
private void ShowImage(int Index)
{
// create image list if needed (once)
if (files == null)
{
files = new DirectoryInfo(picPath).EnumerateFiles().
Where(q => imgExts.Contains(q.Extension.ToLowerInvariant())).
Select( z => z.FullName);
filesCount = files.Count();
}
string thisFile = files.ElementAt(Index);
// no need to dispose an image if you never create one
pb2.ImageLocation = thisFile;
lblImgName.Text = Path.GetFileName(thisFile);
}
而是每次创建文件列表(在2个位置),这样做一次,而不是加载所有这些文件的列表,而是将其保留为IEnumerable
以根据需要获取它们。它也适用于FileInfo
,不区分大小写,主要用于说明一种不同的方式,如果您愿意,可以按创建日期对它们(OrderBy)进行排序。
最后,给定完整路径和文件名,您可以使用.ImageLocation
属性,避免创建和处置Image
。
最重要的是尽量减少重复代码的数量,以便Dont Repeat Yourself。 Next和Previous的代码几乎相同。
答案 1 :(得分:0)
感谢LarsTech和Plutonix指出我的错误。这个新代码现在运行正常:
private void next_Click(object sender, EventArgs e)
{
var filteredFiles = Directory.EnumerateFiles(Path.GetDirectoryName(lfoto_file.FileName))
.Where(file => file.ToLower().EndsWith("jpg") || file.ToLower().EndsWith("png") || file.ToLower().EndsWith("gif") || file.ToLower().EndsWith("bmp") || file.ToLower().EndsWith("tiff") || file.ToLower().EndsWith("ico"))
.ToList();
_pictureIndex++;
if (_pictureIndex >= filteredFiles.Count)
{
_pictureIndex = 0;
}
ibread_img.Image.Dispose();
ibread_img.Image = Image.FromFile(filteredFiles[_pictureIndex]);
init();
}
我只需要过滤掉正确的格式。