Simply being lazy and concurrent

I recently worked on a long running migration project, where we needed to ensure that some of the sql migration scripts were only called once per entity that was migrated, in a threadsafe manner. I looked to the System.Collections.Concurrent namespace, but none of the classes were really a good match. Basically what I needed was the ability to run a part of the migration that was identified by key, but ensure that it would only run once, although different parent strategies might try and run it.

The closest thing I could find was the ConcurrentDictionary. It does however not gurantee that the function passed to GetOrAdd is not called multiple times, and of course I did not really need for it to be a dictionary. I came up with this little implementation, that uses the ConcurrentDictionary internally and combines it with Lazy<T> to ensure that the code only runs once.

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

namespace MyAwesomeSauce
{
    public class OnetimeCollection<TKey>
    {
        private readonly ConcurrentDictionary<TKey, Lazy<string>> concurrentDictionary
            = new ConcurrentDictionary<TKey, Lazy<string>>();

        public void Run(TKey key, Action<TKey> valueFactory)
        {
            var lazyResult = concurrentDictionary.GetOrAdd(key, k =>
                 new Lazy<string>(() => {
                    valueFactory(k);
                    return string.Empty;
                 }, LazyThreadSafetyMode.ExecutionAndPublication));

            var holeInTheGround = lazyResult.Value;
        }
    }
}

With this in place all I needed was a singleton instance, and to wrap each job in a call to Run. Nice and pragmatic solution.