This is more of an academic question... but can ConcurrentDictionary.TryAdd fail? And if so in what cases and why?
Asked
Active
Viewed 3.5k times
84
-
1As it stands, this question is pretty vague. The MSDN [page](http://msdn.microsoft.com/en-us/library/dd267291.aspx) documents a couple of reasons, exceptional and other (as the answers so far have mentioned). – Christian.K Jul 16 '12 at 09:58
-
18yeah and MSDN documentation is known for its clarity and flawlessness – Dave Lawrence Jul 16 '12 at 10:01
-
4Well, it seems clear and flawless enough for the other answers. – Christian.K Jul 16 '12 at 10:02
-
16MSDN may not be perfect, but I've yet to work with a language that's better documented than C#/.NET. With other languages, more often than not, I find myself thinking how much better the documentation would be if it were _more_ like MSDN. – Michael Richardson Sep 10 '14 at 19:09
-
2NET 4.0 We have a case where an ASP.NET Web API application will occasionally fail all subsequent TryAdd calls with an IndexOutOfRangeException. This happens on one server in a pool until the server is pulled and the app pool is reset. We have yet to find a suitable way to address this. – David North Jul 14 '15 at 15:30
3 Answers
123
Yes it can, here are the conditions (from msdn):
- ArgumentNullException - when the key is null reference
- OverflowException - when max number of elements was reached
- It returns false if an element with the same key already exist
Just to reiterate, this is nothing to do with concurrency. If you worry about two threads inserting an item at the same time then the following can happen:
- Both inserts work fine, if the keys are different.
- One insert works fine and returns true, the other insert fails (with no exception) and returns false. This happens if two threads try to insert an item with the same key and basically only one would win and the other would lose.
-
4Ok... so nothing to do with concurrent access.. it's just performs the same checks one would have to do with a standard dictionary. – Dave Lawrence Jul 16 '12 at 09:59
-
1Yes, internally it uses CPU spinning, which allows multiple concurrent connections. – oleksii Jul 16 '12 at 10:02
-
Thanks.. I'm accepting your answer as the most constructive. We're debugging a rather elusive bug here and are ruling out possible sources line by line. I can rule out TryAdd based on what you have contributed (although I'll still add extra logging in case of failure to add) – Dave Lawrence Jul 16 '12 at 10:06
-
2@deveL it is usually very difficult to debug multithreaded applications. But I would trust `System.Collections.Concurrent` namespace as it has been extensively tested. Also take a look at [parallel nunit](http://www.nunit.org/index.php?p=pnunit&r=2.5). I never worked with it, but it seems to address the issue of parallel code unit testing. There should be other frameworks for this if you don't use NUnit. – oleksii Jul 16 '12 at 10:15
-
If one of the inserts returns false due to concurrency fail, is it bad practice to try again? – parliament Feb 10 '17 at 09:30
-
1@parliament trying again would give the same result, making it pointless. Returning false doesn't mean "i failed inserting the item" it's more "something else already inserted the item" – Jim Wolff Aug 23 '17 at 08:58
-
1So if this is nothing to do with concurrency, why does ConcurrentDictionary not have a standard Add method? – Stephen Holt Jun 25 '19 at 15:00
8
Sure it can. If the key already exists, the method will return false.
Ref: http://msdn.microsoft.com/en-us/library/dd267291.aspx
Return Value Type: System.Boolean true if the key/value pair was added to the ConcurrentDictionary successfully. If the key already exists, this method returns false.

Chris Gessler
- 22,727
- 7
- 57
- 83
-
Well... that's a given. Is that the only case where it can fail? – Dave Lawrence Jul 16 '12 at 09:55
-
-
-
1Given that the stated intent of the function is to tell you whether the item has been added, or was already present, I don't think returning false is a failure. – Niall Connaughton Jan 07 '15 at 03:56
1
It will fail when the key already exists in the dictionary.
If the value can't be added because you run out memory, you will get an exception instead.

Guffa
- 687,336
- 108
- 737
- 1,005