Question

Alright, so I'm running into a strange little issue and frankly I'm out of ideas. I wanted to throw this out there to see if I'm missing something that I've done wrong, or if ConcurrentDictionary isn't working correctly. Here's the code:

(Cache is a class containing the static ConcurrentDictionary Keys)

var tmp = Cache.Keys.GetOrAdd(type,
                key =>
                {
                    var keys = context.GetKeys(key);
                    if (keys.Count() == 1)
                    {
                        return new KeyInfo
                            {
                                Name = keys.First().Name,
                                Info = key.GetInfo(keys.First().Name)
                            };
                    }

                    return null;
                });

            if (tmp == null)
                Cache.Keys.TryRemove(type, out tmp);

            return tmp;

The problem is that occasionally tmp is null, causing the TryRemove line to run, yet the return null; line above is never hit. Since that return null is the only thing putting null into the dictionary and it never runs, how could tmp ever be null?


Including the Cache class (SetNames is not used by this code):

public class Cache
{
    public static ConcurrentDictionary<Type, Info> Keys = new ConcurrentDictionary<Type, Info>();
    public static ConcurrentDictionary<Type, string> SetNames = new ConcurrentDictionary<Type, string>();
}
Was it helpful?

Solution 2

I should have closed this a while ago but I completely forgot about it. The example is not thread safe because of TryRemove, but that was only added for debugging purposes. I ended up getting around the problem by rewriting it, so perhaps some of the comments about the code somehow being stale are correct. The code no longer exists to confirm, however.

I'm chalking this one up to user error (my own of course). Thanks for everyone's time!

OTHER TIPS

tmp can be null if you get anything other than a single item set back from context.GetKeys(key). In that case, keys.Count() != 1, and a null item will be inserted into Cache.Keys for the specified key (and returned from GetOrAdd, and assigned to tmp).

EDIT: Just thought of another possibility. What datatype is the key? Is it some kind of custom class? It looks like it is. If so, have you implemented Equals and GetHashcode properly?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top