我正在编写一个多线程下载管理器,其中下载信息由我编写的类(称为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);
}
}
}
编辑 - 更正了示例代码中的错误。
答案 0 :(得分:11)
List<T>
有一个方法
public int RemoveAll(
Predicate<T> match
)
删除与谓词匹配的所有元素:http://msdn.microsoft.com/en-us/library/wdka673a.aspx
因此我建议如下:
download.RemoveAll(x => x.queryComplete());
(请注意,由于== true
已经返回true或false,因此不需要.queryComplete()
。)
答案 1 :(得分: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);
}
}
答案 2 :(得分:1)
Patashu的回答是一般的最佳解决方案,但根据您的示例代码,我建议完全采用另一种方法。
您是否定期轮询下载列表以查找已完成的下载列表?事件订阅可能是更好的解决方案。由于您不熟悉C#,如果您不知道该语言对此模式有内置支持:Events
下载可能会在完成时引发Completed
事件,该事件由管理列表的代码订阅,如:
private void AddDownload(DownloadOperation dl) {
download.Add(dl);
dl.Completed += (s, e) => download.Remove(dl);
}