I use a ConcurrentDictioanry<string, HashSet<string>>
to access some data across many threads.
I read in this article (scroll down) that the method AddOrUpdate
is not executed in the lock, so it could endanger thread-safety.
My code is as follows:
//keys and bar are not the concern here
ConcurrentDictioanry<string, HashSet<string>> foo = new ...;
foreach(var key in keys) {
foo.AddOrUpdate(key, new HashSet<string> { bar }, (key, val) => {
val.Add(bar);
return val;
});
}
Should I enclose the AddOrUpdate
call in a lock
statement in order to be sure everything is thread-safe?
Locking during AddOrUpdate
on its own wouldn't help - you'd still have to lock every time you read from the set.
If you're going to treat this collection as thread-safe, you really need the values to be thread-safe too. You need a ConcurrentSet
, ideally. Now that doesn't exist within the framework (unless I've missed something) but you could probably create your own ConcurrentSet<T>
which used a ConcurrentDictionary<T, int>
(or whatever TValue
you like) as its underlying data structure. Basically you'd ignore the value within the dictionary, and just treat the presence of the key as the important part.
You don't need to implement everything within ISet<T>
- just the bits you actually need.
You'd then create a ConcurrentDictionary<string, ConcurrentSet<string>>
in your application code, and you're away - no need for locking.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With