Используйте Dequeue вместо цикла foreach.Большинство перечислителей становятся недействительными при каждом изменении основного контейнера.И En- / Dequeue являются естественными операциями в очереди.В противном случае вы можете использовать List<T>
или HashSet<T>
while(queue.Count>0)
{
var value=queue.Dequeue();
...
}
Чтобы проверить, был ли предмет уже обработан, HashSet<T>
является быстрым решением.В этих случаях я обычно использую комбинацию HashSet и Queue.Преимущество этого решения состоит в том, что это O (n), потому что проверка и добавление к HashSet
- это O (1).Ваш исходный код был O (n ^ 2), поскольку Contains
на Queue
означает O (n).
Queue<string> queue=new Queue<string>();
HashSet<string> allItems=new HashSet<string>();
void Add(string item)
{
if(allItems.Add(item))
queue.Enqueue(item);
}
void DoWork()
{
while(queue.Count>0)
{
var value=queue.Dequeue();
...
}
}