Question

I have System.Collections.Generic.List _myList and many threads can read from it or add items to it simultaneously. From what I've read I should using 'BlockingCollection' so this will work. I also read about ReaderWriterLockSlim and lock, but I don't figure out how to use them instead of BlockingCollection, so my question is can I do the same with:

  1. ReaderWriterLockSlim
  2. lock

instead of using 'BlockingCollection'. If YES, can you please provide simple example and what pros and cons of using BlockingCollection, ReaderWriterLockSlim, lock?

UPDATED readers will be much more than writers!

Was it helpful?

Solution

ReaderWriterLockSlim:

  • is optimized for use cases, when reads from resourse occur more frequently, than writes;
  • can work with any type of resources (not only collections), because it's just a hybrid synchronization construct.

lock:

  • is a general purpose, rather simple, hybrid synchronization construct without any optimizations; thus, can make performance worse;
  • is a C# wrapper around Monitor class;
  • can work with any type of resources;

BlockingCollection:

  • is a specific type of collection (concrete type of resource), that oriented to solve 'producer-consumer' tasks;
  • supports timeouts and cancellation mechanism (via cancellation tokens), which makes easier integration into code, which uses TPL.

I think, your choice is BlockingCollection (if you really have many readers and writers).

OTHER TIPS

If you are mutating the list frequently, then ReaderWriterLockSlim probably isn't going to help you, as that only allows single write access, and lock is less overhead. Personally, I would just lock (on some lock object) for the duration of each access.

The problem with a BlockingCollection is that it only guarantees that individual operations are atomic - however, quite often we need to perform multiple operations as a unit (more than just TryAdd, etc). So in order to avoid crazy, a lock is simpler.

The other advantage is that the usage of lock is very simple:

lock(syncLock) {
   // do stuff with the list
}

(it also has inbuilt signalling via Monitor.Wait and Monitor.Pulse*, which is nice)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top