2

I've used the ConcurrentDictionary in .Net and fell in love with how easy it is to write concurrent classes using it.

Now, I have a different scenario though. I basically need to keep track of a single object type in an non-duplicated unordered list, so basically a Set<T> type thing, except for it needs all of the thread-safety I've come to expect from ConcurrentDictionary, so having things like GetOrAdd.

Is there anything like this built into .Net?

I've considered just using ConcurrentDictionary and only worrying about the key, and never using the value, but this seems very sub-optimal

Earlz
  • 62,085
  • 98
  • 303
  • 499
  • 1
    Possible duplicate of: http://stackoverflow.com/questions/4306936/how-to-implement-concurrenthashset-in-net – rossipedia Dec 10 '12 at 04:48

1 Answers1

0

No, but you can create a thread-safe set by referencing FSharp.Core.dll and using Microsoft.FSharp.Collections.

Just wrap adds and removes with an interlocked.CompareExhchange.

Performance varies with set size. But you should able to handle several hundred thousand set items.

This handles lots of threads reading and writing to the set.

Also the "Lock" (not really a lock, just the area of atomic actions) is around everything between the lines:

initialSet = sharedSet;

and

done = (initialSet == Interlocked.CompareExchange(ref sharedSet, newSet, initialSet));

 FSharpSet<MyClass> _myItems;

 InterLockedSetAdd(ref _myItems, Item);

    public static void InterLockedSetAdd<T>(ref FSharpSet<T> sharedSet, T item)
    {

        FSharpSet<T> initialSet;
        FSharpSet<T> newSet;
        var spin = new SpinWait();
        bool done = false;

        while (!done)
        {
            initialSet = sharedSet;
            newSet = sharedSet.Add(item);
            done = (initialSet == Interlocked.CompareExchange(ref sharedSet, newSet, initialSet));
            if (!done) spin.SpinOnce();
        }
    } 
Jason Hernandez
  • 2,907
  • 1
  • 19
  • 30
  • 1
    Why use FSharpSet? Why not use HashSet from System.Collections.Generic? – Jeff Yates Jul 10 '14 at 17:15
  • Because `FSharpSet` is immutable. If you used a `HashSet` then the solution wouldn't be thread safe. Nowadays, you could use something like `ImmutableHashSet`. – extremeandy Aug 13 '21 at 04:56