Come implementare un Dictionary senza usare ConcurrentDictionary?
sobes.tech AI
Risposta dell'AI
Per implementare un Dictionary thread-safe senza usare ConcurrentDictionary, puoi utilizzare primitive di sincronizzazione dello spazio dei nomi System.Threading.
Approcci principali:
-
Bloccare l'intero dizionario (
lock): Avvolgere tutte le operazioni di lettura e scrittura in un bloccolockusando lo stesso oggetto di sincronizzazione.// Oggetto per sincronizzare l'accesso al dizionario 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; } }Vantaggi: Implementazione semplice. Svantaggi: Bassa performance in alta concorrenza, poiché si blocca l'accesso a tutto il dizionario anche durante le operazioni di lettura.
-
Utilizzo di
ReaderWriterLockSlim: Permette di separare i blocchi per operazioni di lettura e scrittura. Più thread possono leggere contemporaneamente, ma solo uno può scrivere.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(); } }Vantaggi: Migliore performance rispetto a
lockin operazioni di lettura intensive. Svantaggi: Implementazione più complessa rispetto a un semplicelock.
La scelta tra questi approcci dipende dalle caratteristiche dell'uso del dizionario, dalla proporzione di operazioni di lettura e scrittura e dai requisiti di performance. ReaderWriterLockSlim è generalmente preferibile per operazioni di lettura frequenti.