Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lock for Dictionary.Count

Tags:

c#

locking

Is there any benefit, or harm, in locking when accessing simple properties of a collection, specifically .Count? (is this advisable, inadvisable, or doesn't matter in the slightest?) (Of course I need to lock it on any writes or reads)

private Dictionary<string, bool> database = new Dictionary<string, bool>();
private object databaseLock = new object();
public int Count
{
    get
    {
        lock (databaseLock)
        {
            return database.Count;
        }
    }
}

Personally I'm thinking it might be advisable, simply to hammer down the convention that access to the dictionary needs to be locked, not for any actual reasons[*]. Also the possibility that more operations than one might expect in whatever property you're accessing.

[*] Knowing that in (most) collections in C# the Count is an integer that is maintained by it so should always be an atomic operation

like image 650
Thymine Avatar asked Dec 07 '12 21:12

Thymine


People also ask

Is dictionary values thread-safe?

No. A dictionary is not thread safe.

Is concurrent dictionary thread-safe?

ConcurrentDictionary<TKey,TValue>. This collection class is a thread-safe implementation. We recommend that you use it whenever multiple threads might be attempting to access the elements concurrently.

Are dictionaries thread-safe C#?

As you know, Microsoft in C# already provided a generic collection that is called Dictionary. So why do we need ConcurrentDictionary in C#? The answer is that ConcurrentDictionary provides a thread-safe functionality.


2 Answers

Yes, locking is needed in case of concurrent writes because the docs for Dictionary do not guarantee that this would be safe. You cannot assume anything about its internals.

Exceptions to this rule would require extreme circumstances.

TL;DR: Rely only on documented behavior or you'll find yourself in a world of hurt eventually.

like image 111
usr Avatar answered Oct 17 '22 01:10

usr


This kind of code heavily belongs in the "harm" category. Very serious kind of harm as well. The lock just doesn't protect anything. There's nothing that stops a thread from adding or removing an item from/to the dictionary a nanosecond after the property getter exited the lock. Which makes the Count value you return nothing but garbage. You have no idea how many items are actually in the dictionary when you get the value. By far the most harmful aspect of this bug is that it is usually correct.

This code will guarantee that you created a threading race, by far the worst kind of bug to diagnose.

like image 30
Hans Passant Avatar answered Oct 17 '22 01:10

Hans Passant