Como implementar um Dictionary sem usar ConcurrentDictionary?
sobes.tech IA
Resposta da IA
Para implementar um Dictionary seguro para threads sem usar ConcurrentDictionary, pode-se usar primitivas de sincronização do namespace System.Threading.
Abordagens principais:
-
Bloqueio de todo o dicionário (
lock): Envolver todas as operações de leitura e escrita em um blocolockusando o mesmo objeto de sincronização.// Objeto para sincronizar o acesso ao dicionário 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; } }Vantagens: Implementação simples. Desvantagens: Baixo desempenho em alta concorrência, pois bloqueia o acesso a todo o dicionário mesmo em operações de leitura.
-
Uso de
ReaderWriterLockSlim: Permite separar os bloqueios para operações de leitura e escrita. Vários threads podem ler simultaneamente, mas apenas um pode escrever.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(); } }Vantagens: Melhor desempenho em comparação com
lockem operações intensivas de leitura. Desvantagens: Implementação mais complexa do que com um simpleslock.
A escolha entre essas abordagens depende da natureza do uso do dicionário, da proporção de operações de leitura e escrita, e dos requisitos de desempenho. ReaderWriterLockSlim costuma ser preferido em operações frequentes de leitura.