2014-07-27 2 views
1

Я сталкиваюсь ошибку:Еогеасп петля - коллекция была модифицирована исключение

System.InvalidOperationException: Collection was modified; enumeration operation may not execute.

На протяжении всего моего кода есть хэш-таблицы символов, объектов и т.д., которые постоянно должны быть считаны и удалены. В моем коде используется цикл foreach, чтобы что-то сделать со всеми значениями внутри хэш-таблицы, но говорят, что один символ отключается, так как foreach зацикливается ... и хэш-таблица изменена ... стрела, ошибка.

Обратите внимание, что любой код foreach, который непосредственно изменяет хеш-таблицу, копируется в списки, а родительский список редактируется там, это не проблема. Проблема заключается в чтении хэш-таблиц, которые постоянно редактируются.

Так что я понимаю , что проблема проблема, просто не лучший способ исправить ее. Вот простой пример кода, который иногда бросает коллекции модифицированную ошибку:

foreach (Character CC in World.H_Chars.Values) 
{ 
    if (CC.MyGuild != null && CC.MyGuild.GuildName != G.GuildName 
     && CC.MyGuild.Allies.ContainsValue(G.GuildName)) 
    { 
     CC.MyClient.AddSend(Data); // error on this line 
     CC.MyClient.EndSend(); 
    } 
} 

Так что я думаю, мой вопрос, что это лучший способ, чтобы пройти через хэш-таблицу объектов, которые постоянно вносятся изменения?

+0

Итак .. Вы имеете в виду, что хотите, чтобы он был потокобезопасным? –

+0

Да, я думаю, если это исправит проблему. – user3882530

ответ

0

So I guess my question is what's the best way to go through a Hashtable of Objects that's constantly being modified?

Я подозреваю, что лучший способ не делать. :)

Рассмотрите проблему по-другому. Например, я вижу, что вы ищете данные с определенными характеристиками, которые предположительно являются результатом постоянных изменений в хэш-таблице, которую вы упомянули. Эти изменения являются событиями. Если вы можете организовать такие вещи, чтобы иметь возможность реагировать на эти события в первую очередь, это решит проблему постоянно меняющейся хеш-таблицы, где они впоследствии будут храниться.

+0

Хорошая точка в этом примере. Я переписал его, чтобы вытащить персонажей союзников из менее постоянно изменяющегося списка союзников вместо мирового списка. Вероятно, эта ошибка была решена. Тем не менее я надеялся, что есть лучшее исправление для исключения foreach/modify, потому что код, с которым я работаю, много использует foreach-заявления и поиск альтернатив для всех из них будет трудоемким. – user3882530

0

Вы можете использовать System.Collections.Concurrent.ConcurrentDictionary<TKey, TValue>. Это как структура данных пары ключей: значение, которая является потокобезопасной (например, это общая реализация типа HashTable —, она имеет O (1) поиск элементов). Он может обновляться при перечислении. Тем не менее, вам нужно знать, что при перечислении этого типа коллекции вы, возможно, получаете «грязные» чтения (т. Е. Коллекция, которую вы итерируете, представляет собой моментальный снимок словаря в момент начала итерации —, так что обновления, которые происходят после того, как вы начали повторение, может не отображаться в текущей итерации коллекции).

Существует также System.Collections.Concurrent.ConcurrentBag<T>, который является поточно-безопасным эквивалентом System.Collections.Generic.List<T>.

Смежные вопросы