Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReadOnlyCollection<T> Thread Safety

The documentation for ReadOnlyCollection(of T) states that:

A ReadOnlyCollection(Of T) can support multiple readers concurrently, as long as the collection is not modified. Even so, enumerating through a collection is intrinsically not a thread-safe procedure. To guarantee thread safety during enumeration, you can lock the collection during the entire enumeration. To allow the collection to be accessed by multiple threads for reading and writing, you must implement your own synchronization.

My question regards the bolded part:

  1. why is enumerating through a collection intrinsically not thread-safe
  2. what are the possible implications, and
  3. what are commonly-used workarounds?
like image 449
M.A. Hanin Avatar asked Dec 22 '11 12:12

M.A. Hanin


People also ask

When should I worry about thread safety?

Thread safety becomes a concern if there is at least a single entry point which can be accessed by multiple threads. If a piece of code is accessed by multiple threads and is calling other method/class/etc., then all this code tree becomes vulnerable.

Are C# lists thread-safe?

The ConcurrentBag class is used to create a thread-safe, unordered collection of data in C#. The ConcurrentBag class is very similar to the List in C# and can be used as a thread-safe list in C#.

Is SortedSet thread-safe C#?

SortedSet<T> instance members are not guaranteed to be thread safe, as specified in the documentation.


1 Answers

C# has a pretty good collection model, but the ReadOnlyCollection class is one of the most unfortunately conceived (or named) classes in the entire model. It should have been more appropriately called a readonly list, not a readonly collection.

Now, to get to your question, it is just a read-only decorator of an IList supplied at construction-time. Therefore, the code which constructed the ReadOnlyCollection may modify the original list, with all the consequences that this will have for multithreaded access.

So, enumerating through the collection would have been thread-safe if the collection was truly readonly; but since it is not read-only, it is not thread safe. Given the amount of reputation that you have, I am pretty sure you are not wondering why enumerating through a non-read-only collection is not thread safe.

As for the workaround that you asked, well, you can either use locking, or you can go with the lock-nothing (or lock-as-little-as-possible) principle and make a true read-only copy of the list.

EDIT

I am re-reading my answer many months later, (thanks to asyncwait's comment,) and I realize that I should have answered all of the OP's questions without making assumptions based on his reputation. The OP has probably received his answer by now, but I will do it for the sake of future readers.

Enumerating through a not-really-read-only collection is intrinsically not thread-safe for the same reasons that even in a single-threaded scenario you cannot modify a collection while enumerating it. (ConcurrentModificationException in Java, InvalidOperationException in C#.) In a single-threaded scenario you can make sure that your enumeration code does not attempt to alter the collection in any way, but in a multi-threaded scenario one thread may be enumerating the collection while another thread may be altering it at the same time.

like image 185
Mike Nakis Avatar answered Oct 29 '22 03:10

Mike Nakis