Sobes.tech
Middle+

Ako implementovať Dictionary bez použitia ConcurrentDictionary?

sobes.tech AI

Odpoveď od AI

Za implementáciu thread-safe Dictionary bez použitia ConcurrentDictionary je možné použiť synchronizačné primitíva z priestoru mien System.Threading.

Hlavné prístupy:

  1. Zamknutie celého slovníka (lock): Obaliť všetky operácie čítania a zápisu do bloku lock s použitím toho istého synchronizačného objektu.

    // Objekt na synchronizáciu prístupu ku slovníku
    private readonly object _lockObject = new object();
    private readonly Dictionary<TKey, TValue> _dictionary = new Dictionary<TKey, TValue>();
    
    public void AddOrUpdate(TKey key, TValue value)
    {
        lock (_lockObject)
        {
            if (_dictionary.ContainsKey(key))
            {
                _dictionary[key] = value;
            }
            else
            {
                _dictionary.Add(key, value);
            }
        }
    }
    
    public bool TryGetValue(TKey key, out TValue value)
    {
        lock (_lockObject)
    
        {
            return _dictionary.TryGetValue(key, out value);
        }
    }
    
    public bool TryRemove(TKey key, out TValue value)
    {
        lock (_lockObject)
        {
            if (_dictionary.TryGetValue(key, out value))
            {
                _dictionary.Remove(key);
                return true;
            }
            return false;
        }
    }
    

    Výhody: Jednoduchá implementácia. Nevýhody: Nízka výkonnosť pri vysokej konkurencii, pretože prístup ku celému slovníku je blokovaný aj pri operáciách čítania.

  2. Použitie ReaderWriterLockSlim: Umožňuje rozdelenie zámkov pre operácie čítania a zápisu. Viacero vlákien môže čítať súčasne, ale len jedno môže zapisovať.

    private readonly ReaderWriterLockSlim _lockSlim = new ReaderWriterLockSlim();
    private readonly Dictionary<TKey, TValue> _dictionary = new Dictionary<TKey, TValue>();
    
    public void AddOrUpdate(TKey key, TValue value)
    {
        _lockSlim.EnterWriteLock();
        try
        {
            if (_dictionary.ContainsKey(key))
            {
                _dictionary[key] = value;
            }
            else
            {
                _dictionary.Add(key, value);
            }
        }
        finally
        {
            _lockSlim.ExitWriteLock();
        }
    }
    
    public bool TryGetValue(TKey key, out TValue value)
    {
        _lockSlim.EnterReadLock();
        try
        {
            return _dictionary.TryGetValue(key, out value);
        }
        finally
        {
            _lockSlim.ExitReadLock();
        }
    }
    
    public bool TryRemove(TKey key, out TValue value)
    {
        _lockSlim.EnterWriteLock();
        try
        {
            if (_dictionary.TryGetValue(key, out value))
            {
                _dictionary.Remove(key);
                return true;
            }
            return false;
        }
        finally
        {
            _lockSlim.ExitWriteLock();
        }
    }
    

    Výhody: Lepšia výkonnosť v porovnaní s lock pri intenzívnych operáciách čítania. Nevýhody: Složitá implementácia v porovnaní s jednoduchým lock.

Výber medzi týmito prístupmi závisí od špecifikácií použitia slovníka, pomeru operácií čítania a zápisu a požadovaného výkonu. ReaderWriterLockSlim je zvyčajne preferovaný pri častých operáciách čítania.