The collection has been modified; an enumeration operation may not be performed on a hash table

I have this timer function, it gives me the following exception.
The collection has been modified; an enumeration operation may not be performed as soon as I remove the object from the hash table.

What is the solution to implement similar functionality

void timerFunction(object data) { lock (tMap.SyncRoot) { foreach (UInt32 id in tMap.Keys) { MyObj obj=(MyObj) runScriptMap[id]; obj.time = obj.time -1; if (obj.time <= 0) { tMap.Remove(id); } } } 
+4
source share
3 answers

The traditional way is in your foreach loop to collect the elements that need to be removed, say, in a List. Then, once the foreach loop is done, do another foreach on this list (and not on tMap this time), calling tMap.Remove:

 void timerFunction(object data) { lock (tMap.SyncRoot) { List<UInt32> toRemove = new List<UInt32>(); foreach (UInt32 id in tMap.Keys) { MyObj obj=(MyObj) runScriptMap[id]; obj.time = obj.time -1; if (obj.time <= 0) { toRemove.Add(id); } } foreach (UInt32 id in toRemove) { tMap.Remove(id); } } } 
+10
source

http://social.msdn.microsoft.com/Forums/en-IE/csharplanguage/thread/519c6abc-5b5b-457a-adfb-251ee013d123

  List<string> tablesNamesToRemove = new List<string>(); foreach (string ikey in gridNum.Keys) { Hashtable aux = (Hashtable)gridNum[ikey]; if (aux["OK"].ToString().Trim() == "1") tablesNamesToRemove.Add(ikey); } foreach (string name in tablesNamesToRemove) { gridNum.Remove(name); } 
+2
source

You can create a temporary list and add identifiers for deletion to this list. Then, after the loop finishes, delete all the items in this list:

 void timerFunction(object data) { lock (tMap.SyncRoot) { IList<UInt32> toDelete = new List<UInt32>(); foreach (UInt32 id in tMap.Keys) { MyObj obj=(MyObj) runScriptMap[id]; obj.time = obj.time -1; if (obj.time <= 0) { toDelete.add(id); } } foreach(UInt32 i in toDelete) { tMap.Remove(i); } } 
+2
source

Source: https://habr.com/ru/post/1303304/


All Articles