2013-07-02 54 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

迭代向後在for循環,而不是一個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

不客氣:)(儘管Patashu的LINQ查詢更加簡潔) – 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()已經返回true或false!)

1

Patashu的答案是,一般最好的解決方案,但基於您的示例代碼,我建議採取另一種方法完全。

您是否定期輪詢下載列表以查找完整的下載列表?事件訂閱可能是更好的解決方案。由於您是C#的新手,如果您不知道該語言對此模式有內置支持:Events

下載可能會在其完成時引發一個Completed事件,該事件由代碼訂閱管理清單,如下所示:

private void AddDownload(DownloadOperation dl) { 
    download.Add(dl); 
    dl.Completed += (s, e) => download.Remove(dl); 
} 
相關問題