1

To avoid the famous error:

Collection was modified; enumeration operation may not execute

when iterating an IEnumerator, should I just use ToList() as suggested in this questions, or should I use lock when updating the list?

My concern is that ToList() is simply creating a new list each time, while lock will only have a small delay at some points when updating the list.

So, should I use ToList() or lock?

Community
  • 1
  • 1
Nean Der Thal
  • 3,189
  • 3
  • 22
  • 40
  • 2
    lock doesn't help in case the list is changed on the same thread and ToList doesn't make working with the list thread safe – Steven Feb 16 '14 at 08:25
  • It is in a WCF service, I better check the threading then. I am always confused about threading and WCF. – Nean Der Thal Feb 16 '14 at 08:26
  • Well web-services in general could mean your code is accessed *in theory* on an arbituary thread. In my web services I use `ReadWriterLockSlim` to ensure collection reads are in a read-lock, and obviously a write lock when they are updated. – Moo-Juice Feb 16 '14 at 08:32

1 Answers1

3

The error you are seeing tells you that you are trying to modify collection while you are enumerating it. The lock keyword is applicable in multi-threaded situation and it makes sure your only one thread is in critical section. It has nothing to do with "locking" collection so that you can enumerate it while also modifying it.

The error you are seeing typically occurs with code like below

foreach(var item in items)
{
   //Inside this loop now you are enumerating collection
   //This means you can't add or delete anything from items
   items.Add(newItem);  //This will produce the error you are seeing
}

This error might also occur if you have one thread enumerating collection while other thread adding or removing from collection. So if you know you have multi-threaded situation then you can use probably use lock although it is bit tricky and may impact your concurrency performance and even cause race condition. For multi-threaded situation, using just ToList may not be enough either because you need to make sure only one thread has access to collection while you are calling ToList. So you may need to use ToList along with lock and it may be overall simpler option depending your scenario. To see an example of how to do thread-safe modify-while-enumerate see this answer: Making a "modify-while-enumerating" collection thread-safe.

If you know you don't have multiple thread then ToList is probably your only option and you don't need lock at all. I would also suggest to make sure if you really do need to modify collection while enumerating it. In many cases (but not all), you can do design bit differently to avoid it in first place.

Community
  • 1
  • 1
Shital Shah
  • 63,284
  • 17
  • 238
  • 185
  • I do not modify the list while enumerating it, it is a small caching system and sometimes while reading the list some other function is calling the adding method... – Nean Der Thal Feb 16 '14 at 13:04
  • Is this other function running on separate thread? If so, follow the link in the answer. Otherwise just use ToList as mentioned in answer. – Shital Shah Feb 18 '14 at 10:39