Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is List<T>.Contains() a Threadsafe call - C#

My understanding is that if you are using a generic list (List) in C#, that it can support multiple concurrent readers but only one writer. And when you introduce a writer into the mix, you must also provide synchronization constructs to make the operations thread safe.

Is List.Contains considered a read operation? In other words, if I am calling this method, do I need to worry that a writer may be writing to this List at the same time?

like image 737
adeel825 Avatar asked Apr 10 '09 18:04

adeel825


4 Answers

If you use Reflector to inspect at the code, you get something like this:

public bool Contains(T item)
    {
        if (item == null)
        {
            for (int j = 0; j < this._size; j++)
            {
                if (this._items[j] == null)
                {
                    return true;
                }
            }
            return false;
        }
        EqualityComparer<T> comparer = EqualityComparer<T>.Default;
        for (int i = 0; i < this._size; i++)
        {
            if (comparer.Equals(this._items[i], item))
            {
                return true;
            }
        }
        return false;
    }

As you can see, it is a simple iteration over the items which is definitely a 'read' operation. If you are using it only for reads (and nothing mutates the items), then no need to lock. If you start modifying the list in a separate thread, then you most decidedly need to synchronize access.

like image 189
Erich Mirabal Avatar answered Sep 23 '22 15:09

Erich Mirabal


Yes, you should. Basically I would synchronize for any operation if the list might be used for writing at the same time.

Generally I find collections fall into two categories - ones which are created, initialized and then never changed again (thread-safe), and ones which are mutated over time (not thread-safe, lock for all access).

like image 27
Jon Skeet Avatar answered Sep 25 '22 15:09

Jon Skeet


Yes, you do have to worry! List.Contains just gets an EqualityComparer and then loops through all items the list contains comparing the item passed as parameter with the item at the index of the current iteration, so if the list gets modified while being iterated, results may be unpredictable.

like image 26
em70 Avatar answered Sep 22 '22 15:09

em70


List<T>.Contains is most certainly a read operation. It is possible that some other thread is writing to the collection as you read it.

like image 45
Andrew Hare Avatar answered Sep 22 '22 15:09

Andrew Hare