/// <inheritdoc /> public void Insert(string key, Func <object> factory, TimeSpan?timeout = null, bool isSliding = false, string[] dependentFiles = null) { InnerCache.Insert(key, () => { var result = SafeLazy.GetSafeLazy(factory); var value = result.Value; // force evaluation now - this may throw if cacheItem throws, and then nothing goes into cache // do not store null values (backward compat), clone / reset to go into the cache return(value == null ? null : CheckCloneableAndTracksChanges(value)); }, timeout, isSliding, dependentFiles); }
/// <inheritdoc /> public object Get(string key, Func <object> factory) { var cached = InnerCache.Get(key, () => { var result = SafeLazy.GetSafeLazy(factory); var value = result.Value; // force evaluation now - this may throw if cacheItem throws, and then nothing goes into cache // do not store null values (backward compat), clone / reset to go into the cache return(value == null ? null : CheckCloneableAndTracksChanges(value)); }); return(CheckCloneableAndTracksChanges(cached)); }
/// <inheritdoc /> public object?Get(string key, Func <object?> factory, TimeSpan?timeout, bool isSliding = false, string[]?dependentFiles = null) { // see notes in HttpRuntimeAppCache Lazy <object?>?result; try { _locker.EnterUpgradeableReadLock(); result = MemoryCache.Get(key) as Lazy <object?>; if (result == null || SafeLazy.GetSafeLazyValue(result, true) == null) // get non-created as NonCreatedValue & exceptions as null { result = SafeLazy.GetSafeLazy(factory); var policy = GetPolicy(timeout, isSliding, dependentFiles); try { _locker.EnterWriteLock(); //NOTE: This does an add or update MemoryCache.Set(key, result, policy); } finally { if (_locker.IsWriteLockHeld) { _locker.ExitWriteLock(); } } } } finally { if (_locker.IsUpgradeableReadLockHeld) { _locker.ExitUpgradeableReadLock(); } } //return result.Value; var value = result.Value; // will not throw (safe lazy) if (value is SafeLazy.ExceptionHolder eh) { eh.Exception.Throw(); // throw once! } return(value); }
/// <inheritdoc /> public void Insert(string key, Func <object?> factory, TimeSpan?timeout = null, bool isSliding = false, string[]?dependentFiles = null) { // NOTE - here also we must insert a Lazy<object> but we can evaluate it right now // and make sure we don't store a null value. var result = SafeLazy.GetSafeLazy(factory); var value = result.Value; // force evaluation now if (value == null) { return; // do not store null values (backward compat) } var policy = GetPolicy(timeout, isSliding, dependentFiles); //NOTE: This does an add or update MemoryCache.Set(key, result, policy); }
/// <inheritdoc /> public object Get(string cacheKey, Func <object> getCacheItem) { var result = _items.GetOrAdd(cacheKey, k => SafeLazy.GetSafeLazy(getCacheItem)); var value = result.Value; // will not throw (safe lazy) if (!(value is SafeLazy.ExceptionHolder eh)) { return(value); } // and... it's in the cache anyway - so contrary to other cache providers, // which would trick with GetSafeLazyValue, we need to remove by ourselves, // in order NOT to cache exceptions _items.TryRemove(cacheKey, out result); eh.Exception.Throw(); // throw once! return(null); // never reached }