无法获得.Dispose()在foreach循环工作
所以我有这个foreach循环这里无法获得.Dispose()在foreach循环工作
foreach (string file in condensedFilesList)
{
Image imgToAdd;
imgToAdd = Image.FromFile(file);
if (imgToAdd.Width < 1920 || imgToAdd.Height < 1080)
{
//neither of the commented out lines worked when placed here
//imgToAdd = null;
//imgToAdd.Dispose();
condensedFilesList.Remove(file);
}
else
{
//neither of the commented out lines worked when placed here
//imgToAdd = null;
//imgToAdd.Dispose();
continue;
}
}
它包含指向.jpg图像文件的路径列表。其中约80个各种大小。我需要列表来检查每个图像,检查其分辨率是否为1920 * 1080,如果不是,则从阵列中删除该文件路径指针。
现在它已经过了,将图像设置为在imgToAdd变量中查看,然后如果width属性或height属性不匹配,那么该项目将被删除。这适用于第一个条目。它的分辨率不符合法案,我的阵列将从80个降到79个。
但我无法让我的imgToAdd变量清空,所以我可以为它分配一个新的filePath。我一直在遇到OutOfMemoryException。我试过运行.Dispose(),将它设置为null,并且我无法让它实际上清空它自己的资源。
在调试器中.Dispose()会导致imgToAdd在检查元素时有一长串错误代替值。它的所有属性都在那里,但毫无价值并被错误所取代。如果我将它设置为null,它将起作用,并且在下一次迭代中,imgToAdd = null。 Buuuuut,当它试图为变量分配一个新的filePath时,我仍然会发生OutOfMemoryException。
所以我不知道这是怎么回事。我希望别人能够指出我做错了什么,我看不到它。
EDIT2:
我只是要覆盖此编辑空间,如果人们想检查我更新功能的演变,命中率高达编辑历史。我尝试使用推荐的@dlatikay这样的using(){}语句,并将它写入一个新列表。但不幸的是,我仍然遇到OutOfMemoryException。这里的功能权限
var tempList = new List<string>();
foreach (string file in condensedFilesList)
{
using (Image imgToAdd = Image.FromFile(file))
{
if (imgToAdd.Width < 1920 || imgToAdd.Height < 1080)
{
continue;
}
else
{
tempList.Add(file);
}
}
}
condensedFilesList = tempList;
使用using
。并将结果写入到一个新的列表,这样你就不会被修改源列表,同时枚举它:
var finalList = new List<string>();
foreach (string file in condensedFilesList)
{
using(var imgToAdd = Image.FromFile(file))
{
if (imgToAdd.Width < 1920 || imgToAdd.Height < 1080)
{
/* omit */
}
else
{
finalList.Add(file);
}
}
}
无需分配无效,或者明确地调用Dispose()。 我建议添加try..catch,并非所有的图像文件都是有效的。
上的变量设置为null
您尝试调用一个方法就可以是你的问题的开始,你还可以得到关于修改的集合,你是运行时错误之前顶迭代。以下是我将如何编写该代码以使其正常工作。
foreach (string file in condensedFilesList.ToList())
{
using(var imgToAdd = Image.FromFile(file))
{
if (imgToAdd.Width < 1920 || imgToAdd.Height < 1080)
{
condensedFilesList.Remove(file);
}
}
}
的ToList
将创建一个单独的集合遍历,所以你可以放心地使用condensedFilesList.Remove
。通过将imgToAdd
放入using
声明中,即使发生异常,您也不必担心调用Dispose
,因为它将在声明结束时被调用。
从经验来看,这个ToList()技巧应该与评论一起去。过了一段时间,当代码被重新访问时,我发现它经常被删除,开发人员认为,“这已经是一个列表,不需要这个,*删除*,签入,oops。” – dlatikay
当枚举列表时,无法从列表中删除项目。
for (int i = condensedFilesLists.Length - 1; 0 <= i; --i)
{
using (var image = Image.FromFile(condensedFilesLists[i]))
{
if (image.Width < 1920 || image.Height < 1080)
{
condensedFilesList.Remove(file);
}
}
}
呼叫处理之前使它= null –
即.. imgToAdd。处置();那么imgToAdd = null; –
仅供参考您无法修改您正在迭代的集合。您需要创建一个临时集合来迭代,或者您需要执行一个'for'循环,该循环从最后开始并工作到列表的前面。 – juharr