C# – Concurrent collections, should read methods allow multiple threads at one time

ccollectionsmultithreading

I have custom collection and I want to add wrapper to allow concurrent access.

public class MyConcurrentCollection<T>
{
    private MyCollection _collection; // passed in constructor

    public void Add(T item)
    {
        //modifies and may temporarily "break" the collection while executing this method
    }

    public bool Contains(T item)
    {
        //only reads
    }

    // other read and write methods
}

At this moment, I have object private member that acts as lock in every method, allowing only one thread at a time to access the collection, so every method looks like this:

public bool Contains(T item)
{
    lock(_lock)
    {
        return _collection.Contains(item);
    }
}

However this seems really inefficient. Since Contains() only reads from the collection, should I allow multiple threads into it?

Of course, I need to lock access to Add() and other methods while there are threads in Contains() and I need to block access to Contains() if there is a thread wishing to modify the collection.

Is there any disadvantage of allowing multiple threads into read only methods, or should I stick with my basic solution?

Best Answer

It is inefficient but it is necessary - what happens if you read from the collection while someone else is adding a new entry but, in the way of threading, hasn't quite finished writing the new entry's data?

There are ways to make it more efficient, particularly using a read-write lock, which locks the entire collection to both readers and writers if someone is writing, but allows multiple readers access (ie a read lock prevents a writer - the writer has to wait until you're done reading, but does not block other readers).

Incidentally, using an object as a lock is not considered best practice. Use a dedicated lock construct. I remember reading somewhere the CLR team wish they'd never allowed such use.