How do you set a value in a ConcurrentDictionary regardless of whether it contains the Key

StackOverflow https://stackoverflow.com/questions/21584892

  •  07-10-2022
  •  | 
  •  

Question

First of all, is it safe to simply add an item to a concurrent dictionary using the indexed assignment (e.g. myConcurrentDictionary[someKey] = someValue;)?

I'm just confused because it hides the IDictionary methods (e.g. Add).

Why does AddOrUpdate() require a func to update the value? Is there a method to set the value for a key regardless of whether the key already exists?

I couldn't really gather this from the MSDN page.

Was it helpful?

Solution

  1. Yes, using the indexer should be absolutely fine if you want to add or replace a value.

  2. AddOrUpdate takes a delegate so that you can merge the "old" and "new" value together to form the value you want to be in the dictionary. If you don't care about the old value, use the indexer instead.

  3. The indexer is the way to "set the value for a key regardless of whether the key already exists" just as in any other IDictionary<,> implementation.

The documentation has a neat section at the bottom - a sort of recipe bit - including this:

To do this...
Store a key/value pair in the dictionary unconditionally, and overwrite the value of a key that already exists

Use this method
The indexer’s setter: dictionary[key] = newValue

So it's officially sanctioned.

OTHER TIPS

The indexer will find the pair represented by the given key, add it if it doesn't exist, and replace the value with the given value if it does exist. This operation is logically "atomic" from the point of view of the dictionary. You don't need to worry about the dictionary being corrupted when multiple threads access the dictionary through its indexer concurrently.

Add is hidden because you should generally be using TryAdd instead. Adding could fail if that key is added by another thread after you check if the key exists. This is of course not an issue for the indexer. If another thread adds the item before the current thread does, it'll just overwrite the value, rather than throwing an exception.

AddOrUpdated takes a function for the update for two reasons:

  1. It can use the previous value to determine the updated value.
  2. It's possible that generating the updated value will have side effects, or be an expensive computation. Making it a function allows this operation to be deferred until you know that you do in fact need to update an item.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top