ReadFreeCache
public abstract class ReadFreeCache<TKey, TValue>{protected ReadFreeCache(): this(null){ }protected ReadFreeCache(IEqualityComparer<TKey> comparer){this.m_storage = new Dictionary<TKey, TValue>(comparer);}public abstract TValue Create(TKey key);private Dictionary<TKey, TValue> m_storage;private readonly object m_writeLock = new object();public TValue Get(TKey key){TValue value;if (this.m_storage.TryGetValue(key, out value)){return value;}lock (this.m_writeLock){if (this.m_storage.TryGetValue(key, out value)){return value;}value = this.Create(key);var newStorage = this.m_storage.ToDictionary(p => p.Key,p => p.Value,this.m_storage.Comparer);newStorage.Add(key, value);this.m_storage = newStorage;}return value;}}
___________________________________________________________________________
public abstract class ReadWriteCache<TKey, TValue>{protected ReadWriteCache(): this(null){ }protected ReadWriteCache(IEqualityComparer<TKey> comparer){this.m_storage = new Dictionary<TKey, TValue>(comparer);}private readonly Dictionary<TKey, TValue> m_storage;private readonly ReaderWriterLockSlim m_rwLock = new ReaderWriterLockSlim();protected abstract TValue Create(TKey key);public TValue Get(TKey key){TValue value;this.m_rwLock.EnterReadLock();try{if (this.m_storage.TryGetValue(key, out value)){return value;}}finally{this.m_rwLock.ExitReadLock();}this.m_rwLock.EnterWriteLock();try{if (this.m_storage.TryGetValue(key, out value)){return value;}value = this.Create(key);this.m_storage.Add(key, value);}finally{this.m_rwLock.ExitWriteLock();}return value;}}