0

I have a concurrentdictionary of > lets say object as Artifact.

I wanted to add a new object. The object usually contains list of keys and I have a function to get those keys.

I know how to add to the dictionary if the key doesn't exist but I am not sure how to update the List if the key is already there. Any help would be greatly appreciated

public bool AddToken(Artifact artifact) { IList<string> terms = GetTerms(artifact); foreach(var term in terms) { if (ExistsTerm(term)) { termDictionary.AddOrUpdate(??) }else { IList<Artifact> a = new List<Artifact>(); a.Add(artifact); termDictionary.TryAdd(term, artifact); } } return true; } 
5
  • Would multiple threads be updating this dictionary ? or is it only one thread doing the update ? Commented Sep 7, 2016 at 4:27
  • I think only one thread Commented Sep 7, 2016 at 4:30
  • Then you get var dictArtifactList = termDictionary[<Key>]; as a list. you need a way to compare your current artifact with those in your list. My preference would be to use a LINQ query and do a dictArtifactList.FirstOrDefault(<LAMBDA Comparer>); then update that Artifact in your list. Commented Sep 7, 2016 at 4:38
  • @mmushtaq i checked the link and it is not exactly the same but i got the idea from it. I check if my term[key].contains(artifact) and if not I just add it. Commented Sep 7, 2016 at 4:48
  • ConcurrentDictionary has a totally different set of methods than Dictionary; not at all a duplicate of that linked question. Commented Dec 18, 2018 at 19:36

3 Answers 3

2

Try termDictionary[<key>] = <value>. That will do both add and update (and it will prevent duplicate key exceptions (at the risk of just overwriting the existing data).

Sign up to request clarification or add additional context in comments.

1 Comment

In here, I only have the 1 object artifact, how can i add to the existing list if exist
1

You can use AddOrUpdate.

Conceptually, the AddOrUpdate method will always result in a value change in the collection.

The point of these methods is to resolve problems with the nature of time in concurrent systems. With multiple threads, you cannot predict what elements will be found in the collection at any point of execution.

Here is MSDN Example

class CD_GetOrAddOrUpdate { // Demonstrates: // ConcurrentDictionary<TKey, TValue>.AddOrUpdate() // ConcurrentDictionary<TKey, TValue>.GetOrAdd() // ConcurrentDictionary<TKey, TValue>[] static void Main() { // Construct a ConcurrentDictionary ConcurrentDictionary<int, int> cd = new ConcurrentDictionary<int, int>(); // Bombard the ConcurrentDictionary with 10000 competing AddOrUpdates Parallel.For(0, 10000, i => { // Initial call will set cd[1] = 1. // Ensuing calls will set cd[1] = cd[1] + 1 cd.AddOrUpdate(1, 1, (key, oldValue) => oldValue + 1); }); Console.WriteLine("After 10000 AddOrUpdates, cd[1] = {0}, should be 10000", cd[1]); // Should return 100, as key 2 is not yet in the dictionary int value = cd.GetOrAdd(2, (key) => 100); Console.WriteLine("After initial GetOrAdd, cd[2] = {0} (should be 100)", value); // Should return 100, as key 2 is already set to that value value = cd.GetOrAdd(2, 10000); Console.WriteLine("After second GetOrAdd, cd[2] = {0} (should be 100)", value); } } 

3 Comments

I have read that document before asking the question, I cannot include my function inside there basically.
where you can not include your function?
(term, artifact, (key, list) => list.Add(artifact));
0

ConcurrentDictionary GetOrAdd method get a factory delegate:

var list = termDictionary.GetOrAdd(term, t=>new List<Artifact>()); list.Add(artifact); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.