Using a thread-safe dictionary in .NET C# Part 2: CRUD operations

In the previous post we briefly introduced the ConcurrentDictionary object. We said that it was the thread-safe counterpart of the standard Dictionary object. The Dictionary object is not suited as a shared resource in multi-threaded scenarios as you can never be sure if another thread has added to or removed an element from the dictionary just milliseconds earlier. A ConcurrentDictionary is a good option to cure the shortcomings of the thread-sensitive Dictionary object but it is also more difficult to use.

We’ll briefly look at the 4 Try methods that enable you to insert, remove, update and lookup elements in the ConcurrentDictionary.

The 4 Try methods are the following:

  • TryAdd: the same as the standard Add method of Dictionary but returns false if the element couldn’t be added instead of throwing an exception. The reason for a false outcome is usually that another thread has already added the element with that key
  • TryRemove: the same as the standard Remove method of Dictionary but returns false if the element couldn’t be removed instead of throwing an exception. The reason for a false outcome is usually that another thread has already removed the element with that key
  • TryGet: tries to get an element from the collection by its key and returns false if it wasn’t found. If the element is present then it is returned as an “out” parameter
  • TryUpdate: this is the most difficult case of these 4. It updates the element to a new value but only if the provided comparison parameter matches the existing value

The following example demonstrates these methods:

ConcurrentDictionary<string, int> movieCategoriesOnStock = new ConcurrentDictionary<string, int>();
bool romanceAdded = movieCategoriesOnStock.TryAdd("Romance", 12);
bool actionAdded = movieCategoriesOnStock.TryAdd("Action", 9);

bool horrorAdded = movieCategoriesOnStock.TryAdd("Horror", 10);
Debug.WriteLine("Horror added on first try: {0}", horrorAdded);
bool horrorAddedAgain = movieCategoriesOnStock.TryAdd("Horror", 8);
Debug.WriteLine("Horror added on second try: {0}", horrorAddedAgain);
			
int horror;
bool horrorFound = movieCategoriesOnStock.TryGetValue("Horror", out horror);
Debug.WriteLine("Horror found: {0}", horrorFound);

int comedy;
bool comedyFound = movieCategoriesOnStock.TryGetValue("Comedy", out comedy);
Debug.WriteLine("Comedy found: {0}", comedyFound);

int romance;
bool romanceRemoved = movieCategoriesOnStock.TryRemove("Romance", out romance);
Debug.WriteLine("Romance removed on first try: {0}", romanceRemoved);
bool romanceRemovedAgain = movieCategoriesOnStock.TryRemove("Romance", out romance);
Debug.WriteLine("Romance removed on second try: {0}", romanceRemovedAgain);


bool actionUpdated = movieCategoriesOnStock.TryUpdate("Action", 15, 9);
Debug.WriteLine("Action updated on first try: {0}", actionUpdated);

bool actionUpdatedAgain = movieCategoriesOnStock.TryUpdate("Action", 15, 9);
Debug.WriteLine("Action updated on second try: {0}", actionUpdatedAgain);

foreach (var kvp in movieCategoriesOnStock)
{
	Debug.WriteLine(string.Format("{0}: {1}", kvp.Key, kvp.Value));
}

…which produces the following output:

Horror added on first try: True
Horror added on second try: False
Horror found: True
Comedy found: False
Romance removed on first try: True
Romance removed on second try: False
Action updated on first try: True
Action updated on second try: False
Action: 15
Horror: 10

Warning: beware of the TryUpdate method. It doesn’t throw an exception and is thread-safe but it will only update the value if you know in advance what the existing element has as a value. How can you find that? You can use TryGet but another thread may modify the value just in that very moment and the TryUpdate will fail because you pass in the incorrect value. For a better solution we’ll need to look at another method called AddOrUpdate. We’ll do that next.

View the list of posts on the Task Parallel Library here.

Advertisements

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

ultimatemindsettoday

A great WordPress.com site

Elliot Balynn's Blog

A directory of wonderful thoughts

Robin Sedlaczek's Blog

Developer on Microsoft Technologies

HarsH ReaLiTy

A Good Blog is Hard to Find

Softwarearchitektur in der Praxis

Wissenswertes zu Webentwicklung, Domain-Driven Design und Microservices

the software architecture

thoughts, ideas, diagrams,enterprise code, design pattern , solution designs

Technology Talks

on Microsoft technologies, Web, Android and others

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

Anything around ASP.NET MVC,WEB API, WCF, Entity Framework & AngularJS

Cyber Matters

Bite-size insight on Cyber Security for the not too technical.

Guru N Guns's

OneSolution To dOTnET.

Johnny Zraiby

Measuring programming progress by lines of code is like measuring aircraft building progress by weight.

%d bloggers like this: