There are two ways I\'ve assigned values to a existing key in a concurrent dictionary in my current project.
A. concurrentDictionary1[key] = value
;
They both call TryAddInternal
, so behave exactly the same**.
Update:
There is another difference. Here's the code from the indexer:
set
{
TValue tValue;
if (key == null)
{
throw new ArgumentNullException("key");
}
this.TryAddInternal(key, value, true, true, out tValue);
}
vs. from the method
while (!this.TryAddInternal(key, tValue, false, true, out tValue1));
So it appears there is a chance that the indexer will fail silently, whereas the method will continue trying until it succeeds. Hmm, some more in-depth analysis would be required to fully understand the differences between the two :/
Decompilers are still your friend.
**I derped.
This is an old question, but no one answered why you would use one over the other.
Choose A (the indexer) if you want to add or update and the update is not dependent on the existing value.
Choose B (AddOrUpdate) if you want to add or update and the update depends on an existing value. AddOrUpdate will do the update atomically.
So in the case in the question, you want to use the indexer. It's simpler, easier to read, and probably faster since you aren't creating an anonymous function.
If I know that the 'key' exists, are these functionally equivalent?
The way you're using it, yes. In fact, they're equivalent whether key
exists or not.
What are the reasons for choosing one over the other?
AddOrUpdate
accepts a function to be used to update the value. You're just using it to set the value directly, but it is designed to be used to update the value in a concurrent fashion based on the result of a function. For example:
concurrentDictionary2.AddOrUpdate(key, value, (k, v) => v + value); // adds value to the existing value
Yes equivalent. No. indexers are actually methods (like properties are) and i dont think they bypass concurrency for that. method