3

I've looked around for a while and seen plenty of references to modifying GetHashCode() and things when playing with ContainsKey() and TryGetValue() - but all those issues and examples have all been with some obscure user-specific key.

I have a basic Dictionary<long, object>. When trying either ContainsKey() or TryGetValue(), it doesn't always get a hit (when it should) and moves on to attempting to populate the missing entry (as it technically should if that were the case).

You guessed it: it then complains about the existing key because, well, it exists.

So why is it having problems matching a basic long key and how do you make it behave?

Edit: Code. I have tried several things. In their most basic form:

public void Add(long id)
    {
        if (AreaDataDict.ContainsKey(id)) return;

        AreaData ad = new AreaData(id);
        ad.Load();
        AreaDataDict.Add(id, ad);
    }

Also:

public void Add(long id)
{
    AreaData areaData;
    if (AreaDataDict.TryGetValue(id, out areaData)) return;

    AreaData ad = new AreaData(id);
    ad.Load();
    AreaDataDict.Add(id, ad);
}

Edit 2: No key changes are happening. Other than adding if the value is not found, data is only read from this.

Krenom
  • 1,894
  • 1
  • 13
  • 20
  • 4
    Could you give as an example code when it really fails? It's just guessing unless we can reproduce the problem. – MarcinJuraszek Apr 09 '13 at 15:08
  • 3
    I'm 99.99% sure we'll find this is a bug in your code. Unfortunately, you haven't provided that code, so we can't help you - please provide a short but complete program demonstrating the problem. We can *easily* provide examples of it working, but that won't surprise anyone. – Jon Skeet Apr 09 '13 at 15:09
  • 1
    Example of your code would be very useful. We can try guessing.. – Mariusz.W Apr 09 '13 at 15:09
  • 3
    Is this a multithreaded scenario, by chance? – Anthony Pegram Apr 09 '13 at 15:14
  • Can you post some of your code? Are you not changing the key in another thread or something? – uriDium Apr 09 '13 at 15:14
  • Krenom, can you answer if this is a multithreaded situation against a shared dictionary, keeping in mind if your environment is ASP.NET or another similar multiple concurrent user/thread environment, you could have race conditions. – Anthony Pegram Apr 09 '13 at 15:22
  • 1
    Ugh, yes, it is. Thank you, apparently no one thought about that... I've just switched it to a `ConcurrentDictionary` and all my problems seem to have magically disappeared. – Krenom Apr 09 '13 at 15:28
  • We are completely sure no key changes are happening, because you use `long` for your key type (`TKey`). And `long` is an _immutable_ type, fortunately. Also, we know that `long` has a great `GetHashCode()` implementation, so this cannot be the problem (it often is in other `Dictionary<,>` questions). Of course if you create the dictionary while supplying a bad home-made equality comparer for `long` (an `IEqualityComparer`), it can malfunction, but I guess that is not the case? – Jeppe Stig Nielsen Apr 09 '13 at 16:41

1 Answers1

1

Using a ConcurrentDictionary was the answer, thankfully inspired by user454076.

Krenom
  • 1,894
  • 1
  • 13
  • 20