diff --git a/src/Umbraco.Core/Cache/ObjectCacheAppCache.cs b/src/Umbraco.Core/Cache/ObjectCacheAppCache.cs index c7fc343787..1bdfec2450 100644 --- a/src/Umbraco.Core/Cache/ObjectCacheAppCache.cs +++ b/src/Umbraco.Core/Cache/ObjectCacheAppCache.cs @@ -88,8 +88,10 @@ public class ObjectCacheAppCache : IAppPolicyCache, IDisposable object[] entries; try { - _locker.EnterReadLock(); - + if (_locker.TryEnterReadLock(_readLockTimeout) is false) + { + throw new TimeoutException("Timeout exceeded to the memory cache when getting item"); + } entries = _keys.Where(predicate) .Select(key => MemoryCache.Get(key)) .WhereNotNull() @@ -125,11 +127,15 @@ public class ObjectCacheAppCache : IAppPolicyCache, IDisposable if (result == null || SafeLazy.GetSafeLazyValue(result, true) == null) { result = SafeLazy.GetSafeLazy(factory); + MemoryCacheEntryOptions options = GetOptions(timeout, isSliding); try { - _locker.EnterWriteLock(); + if (_locker.TryEnterWriteLock(_writeLockTimeout) is false) + { + throw new TimeoutException("Timeout exceeded to the memory cache when using factory to insert"); + } // NOTE: This does an add or update MemoryCache.Set(key, result, options); @@ -173,12 +179,26 @@ public class ObjectCacheAppCache : IAppPolicyCache, IDisposable { return; // do not store null values (backward compat) } - MemoryCacheEntryOptions options = GetOptions(timeout, isSliding); - // NOTE: This does an add or update - MemoryCache.Set(key, result, options); - _keys.Add(key); + try + { + if (_locker.TryEnterWriteLock(_writeLockTimeout) is false) + { + throw new TimeoutException("Cannot insert value into cache, due to timeout for lock."); + } + + // NOTE: This does an add or update + MemoryCache.Set(key, result, options); + _keys.Add(key); + } + finally + { + if (_locker.IsWriteLockHeld) + { + _locker.ExitWriteLock(); + } + } } /// @@ -348,6 +368,23 @@ public class ObjectCacheAppCache : IAppPolicyCache, IDisposable } // Ensure key is removed from set when evicted from cache - return options.RegisterPostEvictionCallback((key, _, _, _) => _keys.Remove((string)key)); + return options.RegisterPostEvictionCallback((key, _, _, _) => + { + try + { + if (_locker.TryEnterWriteLock(_writeLockTimeout) is false) + { + throw new TimeoutException("Timeout exceeded to the memory cache when using factory to insert"); + } + _keys.Remove((string)key); + } + finally + { + if (_locker.IsWriteLockHeld) + { + _locker.ExitWriteLock(); + } + } + }); } }