Sobes.tech
Middle+

Hogyan valósítsunk meg egy Dictionary-t anélkül, hogy a ConcurrentDictionary-t használnánk?

sobes.tech MI

Válasz az MI-től

Az ConcurrentDictionary használata nélküli szálbiztos Dictionary megvalósításához a System.Threading névtérből származó szinkronizációs primitíveket lehet alkalmazni.

Fő megközelítések:

  1. Egész szótár zárolása (lock): Minden olvasási és írási műveletet egy lock blokkba foglalunk ugyanazzal a szinkronizációs objektummal.

    // Objektum a szótárhoz való hozzáférés szinkronizálására
    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;
        }
    }
    

    Előnyök: Egyszerű megvalósítás. Hátrányok: Alacsony teljesítmény magas konkurencia esetén, mivel az egész szótár zárolva van még olvasás közben is.

  2. ReaderWriterLockSlim használata: Lehetővé teszi a zárolások szétválasztását olvasási és írási műveletekre. Több szál olvashat egyszerre, de csak egy írhat.

    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();
        }
    }
    

    Előnyök: Jobb teljesítmény olvasási műveletek esetén, mint a lock. Hátrányok: Bonyolultabb megvalósítás, mint az egyszerű lock.

A választás ezek között a megközelítések között a szótár használatának sajátosságaitól, az olvasási és írási műveletek arányától, valamint a teljesítményigényektől függ. A ReaderWriterLockSlim általában előnyösebb gyakori olvasási műveletek esetén.