.NET4.0: streaming update ConcurrentDictionary <TKey, TValue>

By jumping from this thread , I am 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:

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 not identical to the above Remove() implementation.
        foo.AddOrUpdate(bar, 0, (key, n) => (n > 0) ? n - 1 : 0);
    }
}

Is this the right use? Will I remove situations such as:

  • Topic 1: calls to Add ("a"), foo ["a"] is now 1.
  • Thread 1 replaced for Thread 2.
  • Topic 2: calls to Remove ("a"), foo ["a"] is now 0.
  • Thread 2 replaced for Thread 1.
  • Topic 1: Queries foo ["a"] and assumes the value is 1, but it is actually 0.
+5
source share
3 answers

, , ConcurrentDictionary. - , . , , . .

-: ConcurrentDictionary , , , . . .

+3

Add : 0 foo[bar], , 1 foo[bar]. 0, .

Remove : , foo.ContainsKey(bar) - false, 0.

AddOrUpdate?


EDIT: , , , ", ". Remove: , : TryGetValue foo[bar] = currValue - 1. , .

, AddOrUpdate GetOrAdd, , . , , ConcurrentDictionary; UpdateIfExists.

, : Interlocked.Decrement. :

  • 1; foo[bar] 2, currValue.
  • 2 , Add; foo[bar] 3.
  • 1, foo[bar] currValue - 1 = 1.

, , ... , , , : P.

EDIT 2: Interlocked.Decrement: , : (.

+1

: , concurrentdictionary .

, .

If you need a guarantee that the object in the collection will adhere for a number of operations in one thread, assign the object to a local variable in the stream and use only the local variable. Then your stream code doesn't care what happens to the object in the collection.

+1
source

All Articles