无法获得.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; 
+1

呼叫处理之前使它= null –

+0

即.. imgToAdd。处置();那么imgToAdd = null; –

+3

仅供参考您无法修改您正在迭代的集合。您需要创建一个临时集合来迭代,或者您需要执行一个'for'循环,该循环从最后开始并工作到列表的前面。 – juharr

使用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,并非所有的图像文件都是有效的。

+0

嘿,男人,刚刚给了这个镜头仍然得到了内存错误,我已经把最新版本的功能放在编辑部分。有任何想法吗? /: – Chris

+0

请参阅我对OP的最新评论 – dlatikay

上的变量设置为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,因为它将在声明结束时被调用。

+0

从经验来看,这个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); 
     } 
    } 
}