Sobes.tech
Middle+

Ինչպե՞ս իրականացնել Dictionary առանց ConcurrentDictionary օգտագործելու:

sobes.tech AI

Պատասխան AI-ից

Անհրաժեշտ է, որ Dictionary-ի բխող բաշխումը ապահովվի առանց ConcurrentDictionary-ի օգտագործման, կարող եք կիրառել System.Threading տարածքից սինխրոնիզացիայի primitives:

Հիմնական մոտեցումները՝

  1. Բոլոր բառարանի փակումը (lock): Բոլոր ընթերցման և գրելու գործողությունները պետք է պատվեն lock բլոկի մեջ նույն սինխրոնիզացիայի օբյեկտով:

    // Գործիք բառարանի մուտքի սինխրոնիզացման համար
    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;
        }
    }
    

    Արժեքներ: Պարզ իրականացում: Դժվարություններ: Նվազեցված կատարողականություն բարձր մրցակցային պայմաններում, քանի որ ամբողջ բառարանը փակվում է նույնիսկ ընթերցման ժամանակ:

  2. Օգտագործել ReaderWriterLockSlim: Позволяет разделить блокировки для операций чтения и записи. Несколько потоков могут одновременно читать, но только один поток может писать.

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

    Արժեքներ: Բարելավում կատարողականության մեջ ընթերցման գործողությունների դեպքում, քան lock-ի դեպքում: Դժվարություններ: Ավելի բարդ իրականացում, քան պարզ lock-ը:

Ընտրությունը այս մոտեցումների միջև կախված է բառարանի օգտագործման առանձնահատկություններից, ընթերցման և գրելու գործողությունների հարաբերակցությունից և պահանջվող կատարողականությունից: ReaderWriterLockSlim սովորաբար նախընտրելի է հաճախակի ընթերցման գործողությունների դեպքում։