ConcurrentDictionary is a type from .NET 4.0 and System.Collections.Concurrent namespace for handling multiple threads. It allows multiple threads to access a dictionary instance concurrently. This Type makes adding, removing and updating values in a lookup table on multiple threads easier. It's actually a thread safe version of Dictionary collection type that you don’t need to use synchronization. Most of the methods in ConcurrentDictionary are the same as Dictionary methods, but there are some extra methods that I'm gonna to explain them:
TryAdd(): this is an atomic operation to check if the item exist, if not add it. This is a replacement for add();
- public void TryAddTest()
- {
- var concurrentDictionary = new ConcurrentDictionary<string, int>();
- concurrentDictionary.TryAdd("Collection", 1);
- }
TryGetValue() :This is just like the TryGetValue() on the Dictionary.
- public void TryGetValueTest()
- {
- var concurrentDictionary = new ConcurrentDictionary<string, int>();
- int outVal;
- if (concurrentDictionary.TryGetValue("Collection", out outVal))
- {
- //Do something
- }
- }
TryRemove(): this is atomic safe remove a little bit different from remove method of Dictionary. It's second out parameter checks if the key exist or not to remove it.
- public void TryRemoveTest()
- {
- var concurrentDictionary = new ConcurrentDictionary<string, int>();
- int removedValue;
- if (concurrentDictionary.TryRemove("Collection", out removedValue))
- {
- //success
- }
- }
TryUpdate(): This checks if the item is exist and then update the item in one atomic step.
- public void TryUpdateTest()
- {
- var concurrentDictionary = new ConcurrentDictionary<string, int>();
- concurrentDictionary.TryAdd("Machine", 1);
- concurrentDictionary.TryAdd("bicycle", 2);
- concurrentDictionary.TryUpdate("Machine", 200, 4); //this does not do anything, because the value of Machine is not 1 !
- concurrentDictionary.TryUpdate("bicycle", 100, 1); // this will work
- }
GetOrAdd(): make you sure that if an item exist in the cache. It's a thread safe get and insert.
- public void GetOrAddTest()
- {
- var concurrentDictionary = new ConcurrentDictionary<string, int>();
- concurrentDictionary.TryAdd("Machine", 1);
- concurrentDictionary.TryAdd("bicycle", 2);
- // Get motorCycle or add it with value of 4.
- int motorCycle = concurrentDictionary.GetOrAdd("MotorCycle", 4);
- }
AddOrUpdate(): when you want to insert an item into dictionary or update the existing item. This will check if the item exist or not.
- public void AddOrUpdateTest()
- {
- var concurrentDictionary = new ConcurrentDictionary<string, int>();
- concurrentDictionary.TryAdd("Machine", 1);
- concurrentDictionary.TryAdd("bicycle", 2);
- // Add Machine with value of 5 if it does NOT exist.
- // ... Otherwise, add one to its value.
- concurrentDictionary.AddOrUpdate("Machine", 5, (k, v) => v + 4);
- }
AddOrUpdate() and GetOrAdd() they are thread safe but they are not atomic
Resources:
- http://www.dotnetperls.com/concurrentdictionary
- http://geekswithblogs.net/BlackRabbitCoder/archive/2011/02/17/c.net-little-wonders-the-concurrentdictionary.aspx
- http://www.codeproject.com/Articles/548406/Dictionary-plus-Locking-versus-ConcurrentDictionar