0

There is a similar question. The problem that I'm having is that this defied the debugging system. The debugger created the problem.

So I have the following class:

public class Cache<TKey, TData> : Dictionary<TKey, TData>
{
    public TData Get(TKey key, Func<TData> generate)
    {
        if (TryGetValue(key, out TData data))
        {
            return data;
        }
        try
        {
            Add(key, data = generate());
        }
        catch (Exception e)
        {
            Debugger.Break();
        }
        return data;
    }
}

Now If I put a breakpoint in any of my generate functions I get an exception. ArgumentException An item with the same key has already been added.

MotKohn
  • 3,485
  • 1
  • 24
  • 41
  • Possible duplicate of [An item with the same key has already been added](http://stackoverflow.com/questions/5648060/an-item-with-the-same-key-has-already-been-added) – Koby Douek Mar 12 '17 at 05:52
  • Your method is not thread safe. Possibly it is called twice at roughly the same time from two threads. Without the breakpoint you usually get lucky, and the first call finishes before the second starts. With the breakpoint, the second call will always fail. (And as you said below, the debugger may actually call your get method itself too). Consider using a lock. – HugoRune Mar 12 '17 at 08:10
  • It is already resolved, the OP did not realize that his debug watch expressions caused this code to run. – Hans Passant Mar 12 '17 at 08:14
  • What I didn't realize was that even without a watch the debug system collects all the class data. Thanks everyone. – MotKohn Mar 13 '17 at 19:18

2 Answers2

0

I realized that since I use this Get method in Properties. When the app break's the debugger gets all the properties of my class hence all my caches get filled after having checked for the key but before adding it. This was very hard to debug but at least I figured it out. I'm wondering if there is a way to avoid this.

MotKohn
  • 3,485
  • 1
  • 24
  • 41
0

Replace

Add(key, data = generate());

with

this[key] = data = generate();

When you assign via this[index], it will either add or update, depending on whether the key already exists.

John Wu
  • 50,556
  • 8
  • 44
  • 80