public object GetOrAdd(string key, CacheItemRefreshAction refreshAction, long expiration, int lockTimeout) { return GetOrAdd(key, refreshAction, new DefaultCacheItemExpiration(expiration), lockTimeout); }
public object GetOrAdd(string key, CacheItemRefreshAction refreshAction, ICacheItemExpiration expiration, int lockTimeout) { //First try to get the value for the key, if it doesn't exist, then try to add the candidate value. //It's thread safe. The result "ci" for multiple threads should be the exactly the same value. CacheItem candidate = new CacheItem(key, null, refreshAction, expiration); CacheItem ci = SendEvent(OperationType.OP_ADD_OR_GET, candidate) as CacheItem; if (ci == null) { //This should not happen. If it does, then this is a critial bug! LogManager.Warn("CacheManager:Assert Failure", string.Format("The result of GetOrAdd for key [{0}] is null", key)); return null; } //Try to get the value. If there's no valid value, try to refresh it now. object result = null; if ((result = ci.Value) == null) { Stopwatch sw = new Stopwatch(); sw.Start(); if (!m_refreshSyncSem.WaitOne(lockTimeout)) { LogManager.Warn("CacheManager", string.Format("Timeout when try to get a refresh token for [{0}]", ci.Key)); } else { sw.Stop(); int remainTime = lockTimeout - (int)sw.ElapsedMilliseconds; if (remainTime < 0 || remainTime > lockTimeout) { LogManager.Warn("CacheManager", string.Format("Invalid remaining time for [{0}], remainTime=[{1}]", ci.Key, remainTime)); remainTime = 0; } //Now we are allowed to refresh this key ci.RefreshSync(remainTime); //Release the token int prevCount = m_refreshSyncSem.Release(); LogManager.Info("CacheManager", string.Format("Try to refresh [{0}] done, the previous semaphore count is [{1}]", ci.Key, prevCount)); } //get the updated value result = ci.Value; } return result; }
public void Add(string key, object value, CacheItemRefreshAction refreshAction, ICacheItemExpiration expiration) { CacheItem ci = new CacheItem(key, value, refreshAction, expiration); SendEvent(OperationType.OP_ADD, ci); }