2016-12-08 8 views
3

Так что я получил это Еогеасп цикл здесьНе удается получить .Dispose() для работы в цикле Еогеаспа

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 пустым, поэтому я могу назначить ей новый файлPath. Я продолжаю работать в OutOfMemoryException. Я попытался запустить .Dispose(), установив его равным нулю, и я не могу заставить его фактически освободить себя от своих ресурсов.

В отладчике .Dispose() заставляет imgToAdd иметь длинный список ошибок вместо значений при проверке элемента. Все его свойства есть, но бесполезны и заменены ошибками. Если я установил значение = null, он будет работать, а на следующей итерации imgToAdd = null. Buuuuut, я все еще получаю OutOfMemoryException, когда он пытается назначить новую переменную filePath.

Так что я понятия не имею, что с этим. Я надеюсь, что кто-то другой может указать, что я делаю неправильно, я не вижу этого.

EDIT2:

Я просто хочу, чтобы перезаписать это редактировать пространство, если люди хотят, чтобы проверить эволюцию функции, как я обновить, ударяет историю редактирования. Я попытался использовать инструкцию using() {}, например, @dlatikay, и записать ее в новый список. Но, к сожалению, я все еще получаю исключение 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

I.e .. imgToAdd.Dispose(); затем imgToAdd = null; –

+3

FYI Вы не можете изменить коллекцию, которую вы итерируете. Вам нужно либо создать временную коллекцию для итерации, либо вам нужно сделать цикл '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); 
     } 
    } 
} 

Нет необходимости присвоить NULL, или явно называть 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() трюк должен идти с комментарием. Я видел, что он слишком часто удалялся, когда код пересматривался через некоторое время, разработчики думают по очереди: «Это уже список, не нужно для этого, * remove *, check-in, 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); 
     } 
    } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^