public bool Update(TKey key, TValue value, TimeSpan slidingExpiration) { if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) { throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); } try { if (timedStorageIndex.ContainsKey(key)) { timedStorage.Remove(timedStorageIndex[key]); timedStorageIndex.Remove(key); } else { return(false); } TimedCacheKey <TKey> internalKey = new TimedCacheKey <TKey>(key, slidingExpiration); timedStorage.Add(internalKey, value); timedStorageIndex.Add(key, internalKey); return(true); } finally { Monitor.Exit(syncRoot); } }
public object this[TKey key] { get { TValue o; if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) { throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); } try { if (timedStorageIndex.ContainsKey(key)) { TimedCacheKey <TKey> tkey = timedStorageIndex[key]; o = timedStorage[tkey]; timedStorage.Remove(tkey); tkey.Accessed(); timedStorage.Add(tkey, o); return(o); } else { throw new ArgumentException("Key not found in the cache"); } } finally { Monitor.Exit(syncRoot); } } }
public bool TryGetValue(TKey key, out TValue value) { TValue o; if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) { throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); } try { if (timedStorageIndex.ContainsKey(key)) { TimedCacheKey <TKey> tkey = timedStorageIndex[key]; o = timedStorage[tkey]; timedStorage.Remove(tkey); tkey.Accessed(); timedStorage.Add(tkey, o); value = o; return(true); } } finally { Monitor.Exit(syncRoot); } value = default(TValue); return(false); }
/// <summary> /// Purges expired objects from the cache. Called automatically by the purge timer. /// </summary> private void PurgeCache(object sender, System.Timers.ElapsedEventArgs e) { // Only let one thread purge at once - a buildup could cause a crash // This could cause the purge to be delayed while there are lots of read/write ops // happening on the cache if (!Monitor.TryEnter(isPurging)) { return; } DateTime signalTime = DateTime.UtcNow; try { // If we fail to acquire a lock on the synchronization root after MAX_LOCK_WAIT, skip this purge cycle if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) { return; } try { Lazy <List <object> > expiredItems = new Lazy <List <object> >(); foreach (TimedCacheKey <TKey> timedKey in timedStorage.Keys) { if (timedKey.ExpirationDate < signalTime) { // Mark the object for purge expiredItems.Value.Add(timedKey.Key); } else { break; } } if (expiredItems.IsValueCreated) { foreach (TKey key in expiredItems.Value) { TimedCacheKey <TKey> timedKey = timedStorageIndex[key]; timedStorageIndex.Remove(timedKey.Key); timedStorage.Remove(timedKey); } } } finally { Monitor.Exit(syncRoot); } } finally { Monitor.Exit(isPurging); } }
public bool Add(TKey key, TValue value, double expirationSeconds) { if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) { throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); } try { // This is the actual adding of the key if (timedStorageIndex.ContainsKey(key)) { return(false); } else { TimedCacheKey <TKey> internalKey = new TimedCacheKey <TKey>(key, DateTime.UtcNow + TimeSpan.FromSeconds(expirationSeconds)); timedStorage.Add(internalKey, value); timedStorageIndex.Add(key, internalKey); return(true); } } finally { Monitor.Exit(syncRoot); } }