Because the ConcurrentDictionary class includes methods which are not fully atomic. The overloads of GetOrAdd and AddOrUpdate methods which accept delegates as parameters will invoke these delegates outside the synchronization locks.

namespace DotnetCommon.DataStructures
{
    using System.Collections.Generic;
    using System.Threading;

    /// <summary>
    /// Generic Atomic (thread-safe) Dictionary.
    ///
    /// Because the ConcurrentDictionary&lt;TKey, TValue&gt; class includes methods which
    /// are not fully atomic. The overloads of GetOrAdd and AddOrUpdate methods which
    /// accept delegates as parameters will invoke these delegates outside the
    /// synchronization locks.
    /// </summary>
    /// <typeparam name="TKey">The type of the keys in the dictionary.</typeparam>
    /// <typeparam name="TValue">The type of the values in the dictionary.</typeparam>
    /// <remarks>
    ///     <list type="bullet">
    ///         <item><description>Ref: https://www.dotnetcurry.com/csharp/1466/csharp-dotnet-collection-class</description></item>
    ///         <item><description>Also see: https://github.com/microsoft/FASTER/blob/master/cs/src/core/Utilities/SafeConcurrentDictionary.cs</description></item>
    ///         <item><description>Snippet: https://jonlabelle.com/snippets/view/csharp/genericatomic-thread-safe-dictionary-class</description></item>
    ///     </list>
    /// </remarks>
    public class AtomicDictionary<TKey, TValue>
    {
        private readonly ReaderWriterLockSlim _dictionaryLock = new ReaderWriterLockSlim();
        private readonly Dictionary<TKey, TValue> _dictionary;

        public AtomicDictionary()
        {
            _dictionary = new Dictionary<TKey, TValue>();
        }

        public TValue this[TKey key]
        {
            get
            {
                _dictionaryLock.EnterReadLock();
                try
                {
                    return _dictionary[key];
                }
                finally
                {
                    _dictionaryLock.ExitReadLock();
                }
            }
            set
            {
                _dictionaryLock.EnterWriteLock();
                try
                {
                    _dictionary[key] = value;
                }
                finally
                {
                    _dictionaryLock.ExitWriteLock();
                }
            }
        }

        public void Add(TKey key, TValue value)
        {
            _dictionaryLock.EnterWriteLock();
            try
            {
                _dictionary.Add(key, value);
            }
            finally
            {
                _dictionaryLock.ExitWriteLock();
            }
        }

        // ------------------------------------------------------------------------
        // Additional prop/methods below taken from:
        // https://docs.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim#examples
        // ------------------------------------------------------------------------

        public int Count
        {
            get
            {
                _dictionaryLock.EnterReadLock();
                try
                {
                    return _dictionary.Count;
                }
                finally
                {
                    _dictionaryLock.ExitReadLock();
                }
            }
        }

        public AddOrUpdateStatus AddOrUpdate(
            TKey key,
            TValue value,
            IEqualityComparer<TValue> valueEqualityComparer = null
        )
        {
            valueEqualityComparer ??= EqualityComparer<TValue>.Default;

            _dictionaryLock.EnterUpgradeableReadLock();
            try
            {
                TValue result;
                if (_dictionary.TryGetValue(key, out result))
                {
                    if (valueEqualityComparer.Equals(result, value))
                    {
                        return AddOrUpdateStatus.Unchanged;
                    }
                    else
                    {
                        _dictionaryLock.EnterWriteLock();
                        try
                        {
                            _dictionary[key] = value;
                        }
                        finally
                        {
                            _dictionaryLock.ExitWriteLock();
                        }

                        return AddOrUpdateStatus.Updated;
                    }
                }
                else
                {
                    _dictionaryLock.EnterWriteLock();
                    try
                    {
                        _dictionary.Add(key, value);
                    }
                    finally
                    {
                        _dictionaryLock.ExitWriteLock();
                    }

                    return AddOrUpdateStatus.Added;
                }
            }
            finally
            {
                _dictionaryLock.ExitUpgradeableReadLock();
            }
        }

        public enum AddOrUpdateStatus
        {
            Added,
            Updated,
            Unchanged
        }

        public bool AddWithTimeout(TKey key, TValue value, int timeout)
        {
            if (_dictionaryLock.TryEnterWriteLock(timeout))
            {
                try
                {
                    _dictionary.Add(key, value);
                }
                finally
                {
                    _dictionaryLock.ExitWriteLock();
                }

                return true;
            }

            return false;
        }

        public void Remove(TKey key)
        {
            _dictionaryLock.EnterWriteLock();
            try
            {
                _dictionary.Remove(key);
            }
            finally
            {
                _dictionaryLock.ExitWriteLock();
            }
        }

        ~AtomicDictionary()
        {
            _dictionaryLock?.Dispose();
        }
    }
}