Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread safe Increment in C#

I am trying to Increment an element in a list in C#, but I need it to be thread safe, so the count does not get affected.

I know you can do this for integers:

Interlocked.Increment(ref sdmpobjectlist1Count);

but this does not work on a list I have the following so far:

lock (padlock)
{
     DifferenceList[diff[d].PropertyName] = DifferenceList[diff[d].PropertyName] + 1;
}

I know this works, but I'm not sure if there is another way to do this?

like image 203
jg943 Avatar asked Apr 08 '13 20:04

jg943


2 Answers

As David Heffernan said, ConcurrentDictionary should provider better performance. But, the performance gain might be negligible depending upon how frequently multiple threads try to access the cache.

using System;
using System.Collections.Concurrent;
using System.Threading;

namespace ConcurrentCollections
{
    class Program
    {
        static void Main()
        {
            var cache = new ConcurrentDictionary<string, int>();

            for (int threadId = 0; threadId < 2; threadId++)
            {
                new Thread(
                    () =>
                    {
                        while (true)
                        {
                            var newValue = cache.AddOrUpdate("key", 0, (key, value) => value + 1);
                            Console.WriteLine("Thread {0} incremented value to {1}",
                                Thread.CurrentThread.ManagedThreadId, newValue);
                        }

                    }).Start();
            }

            Thread.Sleep(TimeSpan.FromMinutes(2));
        }
    }
}
like image 122
Faisal Mansoor Avatar answered Nov 11 '22 21:11

Faisal Mansoor


If you use a List<int[]> rather than a List<int>, and have each element in the list be a single-item array, you will be able to do Increment(ref List[whatever][0]) and have it be atomic. One could improve storage efficiency slightly if one defined

class ExposedFieldHolder<T> {public T Value;}

and then used a List<ExposedFieldHolder<int>> and used the statement Increment(ref List[whatever].Value) to perform the increment. Things could be more efficient yet if the built-in types provided a means of exposing an item as a ref or allowed derived classes sufficient access to their internals to provide such ability themselves. They don't, however, so one must either define one's own collection types from scratch or encapsulate each item in its own class object [using an array or a wrapper class].

like image 37
supercat Avatar answered Nov 11 '22 19:11

supercat