class Sample
{
private List<int> _list;
public List<int> List
{
get
{
return _list.Select(p => p + p).Where(q => q % 2 == 0).ToList();
}
}
public void Add(int n)
{
_list.Add(n);
}
public void Remove(int n)
{
_list.Remove(n);
}
}
I have a situation similar to above in a multithreaded environment where Add
, Remove
and List
are accessed by multiple threads simultaneously.
In some cases Collection was modified; enumeration operation may not execute
is thrown in the List
getter, which makes sense as threads can Add/Remove while the Select/Where operations are executing.
Can the list be modified by another thread during a call to ToList()
? Meaning, would changing the getter to
return _list.ToList().Select(p => p + p).Where(q => q % 2 == 0);
be enough, or do I need to resort to locks around access to _list
There's no multi-threading protection in List<T>
, so yes, another thread could modify the list during a ToList
call. The results could be:
Basically, it is not safe to use a List<T>
from multiple threads without external synchronization, unless all the threads are just reading from it. You either need synchronization (e.g. using SynchronizedCollection<T>
instead of List<T>
, or handling the synchronization yourself), or a concurrent collection such as ConcurrentBag<T>
.
See more on this question at Stackoverflow