Jumping off from this thread, I'm trying to use ConcurrentDictionary to replicate the following:
public static class Tracker
{
private static Dictionary<string, int> foo = new Dictionary<string, int>();
private static object myLock = new object();
public static void Add(string bar)
{
lock(myLock)
{
if (!foo.ContainsKey(bar))
foo.Add(bar, 0);
foo[bar] = foo[bar] + 1;
}
}
public static void Remove(string bar)
{
lock(myLock)
{
if (foo.ContainsKey(bar))
{
if (foo[bar] > 0)
foo[bar] = foo[bar] - 1;
}
}
}
}
My initial attempt is:
public static class Tracker2
{
private static ConcurrentDictionary<string, int> foo =
new ConcurrentDictionary<string, int>();
public static void Add(string bar)
{
foo.AddOrUpdate(bar, 1, (key, n) => n + 1);
}
public static void Remove(string bar)
{
// Adding a 0'd item may be ok if it wasn't there for some reason,
// but it's not identical to the above Remove() implementation.
foo.AddOrUpdate(bar, 0, (key, n) => (n > 0) ? n - 1 : 0);
}
}
Is this correct usage? Will I avoid situations such as:
- Thread 1: calls Add("a"), foo["a"] is now 1.
- Thread 1 is swapped out for Thread 2.
- Thread 2: calls Remove("a"), foo["a"] is now 0.
- Thread 2 is swapped out for Thread 1.
- Thread 1: Requests foo["a"] and assumes the value is 1 but it's actually 0.