无法让 .Dispose() 在 foreach 循环中工作

Can't get .Dispose() to work in a foreach loop

所以我在这里得到了这个 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 变量中设置要查看的图像,然后如果宽度 属性 或高度 属性 不匹配,则删除该项目。这适用于第一个条目。它的分辨率不符合要求,我的数组将从 80 个条目减少到 79 个条目。

但是我无法将 imgToAdd 变量清空,因此我可以为其分配一个新的文件路径。我将 运行 保存到 OutOfMemoryException 中。我试过 运行.Dispose(),将其设置为 null,但我无法让它真正清空其自身的资源。

在调试器中,当您检查元素时,.Dispose() 会导致 imgToAdd 出现一长串错误来代替值。它的所有属性都在那里,但毫无价值并被错误所取代。如果我将它设置为 null,它将起作用,并且在下一次迭代中,imgToAdd = null。 Buuuuut,当它尝试为变量分配新的文件路径时,我仍然遇到 OutOfMemoryException。

所以我不知道这是怎么回事。我希望其他人可以指出我做错了什么,我看不到。

编辑2:

我只是要覆盖这个编辑 space,如果人们想在我更新时检查功能的演变,请点击编辑历史。我尝试使用 @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;

除了在您尝试对其调用方法之前将变量设置为 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,因为即使发生异常,它也会在语句末尾被调用。

当正在枚举列表时,您不能从列表中删除项目。

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);
        }
    }
 }

使用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);
        }
    }
}

无需分配 null 或显式调用 Dispose()。 我建议添加 try..catch,不是所有的图像文件都有效。