public TKey this[int i] { get { TKey o; if (!Monitor.TryEnter(syncRoot, MAX_LOCK_WAIT)) { throw new ApplicationException("Lock could not be acquired after " + MAX_LOCK_WAIT + "ms"); } try { if (timedStorage.Count > i) { TimedCacheKey <TKey> tkey = timedStorage[i]; o = tkey.Key; timedStorage.Remove(tkey); tkey.Accessed(); timedStorage.Insert(i, tkey); return(o); } else { throw new ArgumentException("Key not found in the cache"); } } finally { Monitor.Exit(syncRoot); } } set { AddOrUpdate(value, DefaultTime); } }
public bool Update(TKey key, 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); timedStorageIndex.Add(key, internalKey); return(true); } finally { Monitor.Exit(syncRoot); } }
/// <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 { OpenMetaverse.Lazy <List <object> > expiredItems = new OpenMetaverse.Lazy <List <object> >(); foreach (TimedCacheKey <TKey> timedKey in timedStorage) { if (timedKey.ExpirationDate < signalTime) { // Mark the object for purge expiredItems.Value.Add(timedKey.Key); } } 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); } }