Sobes.tech
Middle+

Kuidas rakendada Dictionary't, kasutamata ConcurrentDictionary't?

sobes.tech AI

Vastus AI-lt

Süsteemivälise Dictionary-i sünkroonimiseks ilma ConcurrentDictionary-t kasutamata saab rakendada System.Threading nimetusruumi primitiive.

Peamised lähenemised:

  1. Kogu sõnastiku lukustamine (lock): Kõigi lugemis- ja kirjutamisoperatsioonide ümbritsemine lock-iga sama sünkroonimisobjekti kasutades.

    // Objekt sõnastiku juurdepääsu sünkroniseerimiseks
    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;
        }
    }
    

    Plussid: Lihtne rakendus. Miinused: Madal jõudlus suure konkurentsi korral, kuna lukustatakse kogu sõnastik isegi lugemisoperatsioonide ajal.

  2. `ReaderWriterLockSlim`` kasutamine: Võimaldab eraldada lukud lugemis- ja kirjutamisoperatsioonidele. Mitmed vood võivad samaaegselt lugeda, kuid ainult üks voog saab kirjutada.

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

    Plussid: Parema jõudlusega võrreldes lock-iga intensiivsete lugemisoperatsioonide korral. Miinused: Keerulisem rakendus kui lihtsa lock-iga.

Valik nende lähenemisviiside vahel sõltub sõnastiku kasutamise spetsiifikast, lugemis- ja kirjutamisoperatsioonide suhteist ning nõutavast jõudlusest. ReaderWriterLockSlim on tavaliselt eelistatum sagedaste lugemiste korral.