There are several threadsafe types available in the System.Collections.Concurrent namespace and elsewhere in the framework. Using these may be the simplest option.
You could also perform your own explicit locking using the lock
statement. E.g.
public class Foo
{
private readonly List<int> list = new List<int>();
private readonly object locker = new object();
public void SomeCommand(Bar bar)
{
lock (this.locker)
{
// do something here?
this.list.Add(..);
// do something here?
}
}
public Baz SomeQuery()
{
lock (this.locker)
{
// do something here?
this.list.Select(...);
// do something here?
}
}
public void SomethingElseEntirely()
{
lock (this.locker)
{
// do something here
}
}
}
The best option varies from case to case. E.g. do you want to also synchronize operations other than just the collection manipulations (as indicated in the code sample), do you want to performance tune for more reads than writes or more writes than reads (some of the built in types are already tuned in these ways), etc.
You could also experiment with other explicit thread synchronization types, such as ReaderWriterLockSlim which is optimised for more reads than writes, and see what fits your scenario best.