2013-07-02 19 views
5

Piszę wielowątkowy menedżer pobierania, w którym informacje o pobieraniu są zarządzane przez klasę, którą napisałem (nazywane DownloadOperation). Pliki do pobrania są przechowywane na liście (nazywane pobieraniem). Muszę usunąć obiekty z listy, gdy funkcja w klasie (queryCompleted) zwraca wartość true, ale okazało się, że elementów nie można usunąć z list z pętli foreach. Jaki jest najlepszy sposób na uzyskanie tego samego efektu. Jestem stosunkowo nowy w C#, więc wybacz moją głupotę.Usuwanie pozycji z listy po spełnieniu warunku

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

Edytuj - poprawiono błąd w przykładowym kodzie.

Odpowiedz

3

Iterate wstecz w pętli for zamiast pętli 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

Dziękuję bardzo! To wydaje się działać idealnie. – user2544563

+0

Nie ma za co :) (chociaż zapytanie LINQ firmy Patashu jest dużo bardziej zwięzłe) – keyboardP

+1

+1 Kluczem jest to, że nie używasz obiektu 'IEnumerator'. –

11

List<T> ma metodę

public int RemoveAll(
    Predicate<T> match 
) 

który usuwa wszystkie elementy pasujące predykat: http://msdn.microsoft.com/en-us/library/wdka673a.aspx

Proponuję zatem coś podobne:

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

(zauważ, że == true nie jest potrzebna, ponieważ .queryComplete() już zwraca prawdę lub fałsz!)

1

odpowiedź Patashu jest najlepszym rozwiązaniem w ogóle, ale w oparciu o przykładowy kod Sugerowałbym biorąc zupełnie innego podejścia.

Czy okresowo odpytujesz listę pobierania, aby znaleźć ukończone? Subskrypcja zdarzeń prawdopodobnie byłaby lepszym rozwiązaniem. Ponieważ jesteś nowy w języku C#, na wypadek, gdyby nie wiesz, że język ma wbudowaną obsługę tego wzorca: Events

Pobranie może spowodować powstanie zdarzenia Completed, które jest subskrybowane przez kod, który zarządza listą, coś w stylu:

private void AddDownload(DownloadOperation dl) { 
    download.Add(dl); 
    dl.Completed += (s, e) => download.Remove(dl); 
} 
Powiązane problemy