Collection Was Modified; Enumeration Operation May Not Execute in Arraylist

Collection was modified; enumeration operation may not execute in ArrayList

You are removing the item during a foreach, yes? Simply, you can't. There are a few common options here:

  • use List<T> and RemoveAll with a predicate
  • iterate backwards by index, removing matching items

    for(int i = list.Count - 1; i >= 0; i--) {
    if({some test}) list.RemoveAt(i);
    }
  • use foreach, and put matching items into a second list; now enumerate the second list and remove those items from the first (if you see what I mean)

Collection was modified; enumeration operation may not execute

What's likely happening is that SignalData is indirectly changing the subscribers dictionary under the hood during the loop and leading to that message. You can verify this by changing

foreach(Subscriber s in subscribers.Values)

To

foreach(Subscriber s in subscribers.Values.ToList())

If I'm right, the problem will disappear.

Calling subscribers.Values.ToList() copies the values of subscribers.Values to a separate list at the start of the foreach. Nothing else has access to this list (it doesn't even have a variable name!), so nothing can modify it inside the loop.

Collection was modified; enumeration operation may not execute. C#

foreach (PC_list x in onlinelist)
{
onlinelist.Remove(x); // cannot do this
}

This is the heart of the problem. You cannot remove an item from a collection as you are iterating over it in a foreach. Your options are to make a local copy of the list prior to the loop, loop over the copy, and remove from the original. Or you can keep a separate list of items to remove after you finish the original loop. Or you can switch to a for loop and iterate over it backwards, which allows you to remove items from the end as you go.

While you're here, if you are not stuck working with C# 1 / .NET 1.1 / Visual Studio 2003, you might want to consider switching from ArrayList to the stronger List<T>, where T is the type of the object in the collection. In your case, that would be a List<PC_list>. You can find it at System.Collections.Generic.List<T>.

And since your question is tagged multithreading, it would also be a smart idea to consult the collections built with concurrency in mind.

Collection was modified; enumeration operation may not execute

Microsoft specifies that any object which implements iEnumerable must void any existing enumerations when the object is modified. The general reason for this requirement is that, for many types of collections, it is difficult to ensure that an enumerator will behave sensibly when a collection is modified. For example, suppose a List holds five values (A,B,C,D,E) and an enumerator works by setting n to the number of elements, and then outputting element(0), element(1), etc. up to element(n-1). If, while the enumerator is enumerating element(2) [C], an element BB is inserted after element(1) [i.e. B], the enumerator might then proceed to output element (3) [which is C, again], then element 4 [D], and then decide it's done since it output all five elements. That would be a bad situation (one element showed up twice, and one went missing).

It is certainly reasonable that an enumerator should be invalidated if a collection is modified in a way that would prevent the enumerator from yielding sensible results. To my mind, however, enumerators that are capable of meeting the following contract should do so, even if a collection is modified, rather than throwing exceptions:

  1. Any item which exists throughout the duration of enumeration must be returned exactly once.
  2. Any item which exists for part of the duration of enumeration must be returned exactly once or not at all, but there is no requirement regarding which such items (if any) are returned.
  3. The sequence in which the items are returned must be a valid sequence for the enumerator (e.g. a SortedList must return items in sorted sequence; if an item gets added to the list which would precede an already-output item, that item must not be enumerated).
  4. For purposes of (1) and (2), an item which is removed shall be considered distinct from one which is added, even if the keys are identical; if an item's key is changed, the item before the change is considered distinct from the item after.
  5. Repeated enumerations via Reset are not guaranteed to return the same items.

The VB6-style Collection seems to comply with the above semantics, but none of the other standard collections do. Too bad--such requirements could be met reasonably well by some data structures, but would be sufficient to avoid the duplication of list data which is frequently necessary under the current rules.

C# Collection was modified; enumeration operation may not execute

Any collection that you iterate over with foreach may not be modified during iteration.

So while you're running a foreach over rankings, you cannot modify its elements, add new ones or delete any.



Related Topics



Leave a reply



Submit