2016-12-08 28 views
3

所以我有這個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

回答

4

使用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

4

上的變量設置爲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

0

當枚舉列表時,無法從列表中刪除項目。

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