Since the first .NET Framework version, most of the collections in the System.Collections
namespace contained the Synchronized
factory method that creates a thread safe wrapper over the collection instance, which ensures thread safety:
var source = Enumerable.Range(1, 42000).ToList(); var destination = ArrayList.Synchronized(new List<int>()); Parallel.ForEach(source, n => { destination.Add(n); }); Assert.AreEqual(source.Count, destination.Count);
The synchronized collection wrapper can be used in a concurrent environment, but its efficiency is low, since it uses simple locking ensuring exclusive collection access for every operation. This approach is called coarse-grained locking and it is described in Chapter 3, Understanding Parallelism Granularity. It does not scale well with an increase in the number of clients and the amount of data inside the collection.
A complicated, but an efficient, approach is to use fine-grained locking...