Collection was modified; enumeration operation may not execute . Exception ?

  • Thread starter Thread starter Anders Both
  • Start date Start date
A

Anders Both

My client-server system, is begining (when more client are connected)
sometimes to throw an exception like this:

Collection was modified; enumeration operation may not execute.

foreach (tcClient per in tcClientList) <-- Exception throw by this line.
{
if (tcClient!=tcClientNow) tcClient.flush();
}

Does someone have a good advice about how to handle this situation. I know
that I can lock and use volatile and stuff. But the performance of the
system is wery important, and I feel that videly use of locking and
volatile, can cause slover performance.

1. How can I lock the enumeration so that other thread cannot alter or add
element to tcClientList, while enumerating.

2. How can I just ignore the exception completly.

Best Regards

Anders Both, Denmark.
 
the code should be :
foreach (TcClient tcClient in tcClientList) <-- Exception throw by this
line.
{
if (tcClient!=tcClientNow) tcClient.flush();
}
to make sence, sorry. (but ofcause the question is still very valid)
 
The error means that you run the risk of stepping over items in the list
if some items are removed or added.
It's safer to use a for loop in this case, also if flush actually removes
an item from the list it's better to traverse the list in reverse order

for(int i = tcClientList.Count - 1; i >= 0; i--)
{
TcClient tcClient = (TcClient)tcClientList;

if(tcClient != tcClientNow)
{
tcClient.flush();
}
}

Still not sure why you would get this error as I can't see anything being
added or removed
 
The for loop is not any safer, you can keep the foreach statement!

Your problem is probably due to another thread modifying the list while you
enumerate it.
So, you need synchronization like:

lock(tcClientList.SyncRoot)
{
foreach (TcClient tcClient in tcClientList)
...
}

You also need the lock(tcClientList.SyncRoot) in the methods that modify the
list. This way, the list cannot be modified by another thread while you are
enumerating it.

Bruno.

"Morten Wennevik" <[email protected]> a écrit dans le message de
The error means that you run the risk of stepping over items in the list
if some items are removed or added.
It's safer to use a for loop in this case, also if flush actually removes
an item from the list it's better to traverse the list in reverse order

for(int i = tcClientList.Count - 1; i >= 0; i--)
{
TcClient tcClient = (TcClient)tcClientList;

if(tcClient != tcClientNow)
{
tcClient.flush();
}
}

Still not sure why you would get this error as I can't see anything being
added or removed
 
Back
Top