2013-07-02 6 views
5

Я пишу многопотоковый менеджер загрузок, в котором информация о загрузке управляется классом, который я написал (называется DownloadOperation). Загрузки хранятся в списке (называемом загрузкой). Мне нужно удалить объекты из списка, когда функция класса (queryCompleted) возвращает true, но выяснила, что элементы не могут быть удалены из списков из цикла foreach. Каков наилучший способ получить тот же эффект. Я относительно новичок в C#, так что помилуй мою глупость.Удаление элементов из списка при выполнении условия

private void removeInactiveDownloads() 
    { 
     foreach (DownloadOperation dl in download) 
     { 
      if (dl.queryComplete() == true) 
      { 
       // if download is no longer in progress it is removed from the list. 
       download.Remove(dl); 
      } 
     } 
    } 

Редактировать - Исправлена ​​ошибка в примере кода.

ответ

3

Итерация назад в цикле вместо петли Foreach

for(int i = download.Count; i >= 0; i--) 
{ 
    if (download[i].queryComplete()) 
    { 
     // if download is no longer in progress it is removed from the list. 
     download.RemoveAt(i); 
    } 
} 
+0

Большое спасибо! Кажется, это работает отлично. – user2544563

+0

Добро пожаловать :) (хотя запрос LINQ от Patashu намного более краткий) – keyboardP

+1

+1 Ключевым моментом является то, что вы не используете объект IEnumerator. –

11

List<T> имеет метод

public int RemoveAll(
    Predicate<T> match 
) 

, которая удаляет все элементы, соответствующие предикат: http://msdn.microsoft.com/en-us/library/wdka673a.aspx

Поэтому я предложить что-то подобный:

download.RemoveAll(x => x.queryComplete()); 

(обратите внимание, что == true не требуется, так как .queryComplete() уже возвращает истину или ложь!)

1

ответ Patashu является лучшим решением в целом, но, основываясь на вашем примере кода, я хотел бы предложить, принимая другой подход в целом.

Периодически вы просматриваете список загрузок, чтобы найти завершенные? Вероятно, это будет лучшее решение. Поскольку вы не знакомы с C#, если вы не знали, что язык имеет встроенную поддержку для этого шаблона: Events

Загрузка может привести к событию Completed, когда он будет завершен, на который подписан код, который управляет списком, что-то вроде:

private void AddDownload(DownloadOperation dl) { 
    download.Add(dl); 
    dl.Completed += (s, e) => download.Remove(dl); 
} 
Смежные вопросы