简体   繁体   中英

C# Collection was modified exception on lambda.where

I have the following code:

var actionsToExecute = _messagesToExecute.Where(m => m.CanExecute).ToList();

It runs fine 99% of the time, but every once in a while it will crash with the exception:

Collection was modified; enumeration operation may not execute

I am a bit lost as it seems a bit random. This is the first line in the method. What might cause a lambda expression to throw this exception?

It has to do with threading. It seems like this is website code. If that private variable is modified by another person visiting the site while the .ToList() is executing that exception will occur.

The solution is to use a threadsafe collection but this isn't optimal since if many people are reading/writing to it they can only do it more or less one at a time.

I had a similar problem but the enumeration was not critical, it was okay to have skips or duplicates so I implemented my own enumerator that does not check to see if it was modified.

You either need to use lock() around all your references to _messagesToExecute, or you could use something from System.Collections.Concurrent which handle locking the collection internally.

eg

_messagesToExecute = new ConcurrentBag<TMessage>();

or if you'd rather use locking:

static readonly object m_lock = new object();

then whenever you update the list:

lock(m_lock){
  _messagesToExecute.Add(item);
}

and then when you're pulling out the list:

lock(m_lock){
    var actionsToExecute = _messagesToExecute.Where(m => m.CanExecute).ToList();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM