private TReturnType ReadAllCache <TReturnType>(Func <IDictionary <string, T>, TReturnType> func) { _cacheLock.EnterReadLock(); try { var cache = MemoryCache.Default; var lastChange = _cacheProvider.LastChanged; var savedLastChange = cache[_cacheUpdateNumberKey] as long?; if (cache[_cacheKey] is IDictionary <string, T> result && savedLastChange == lastChange) { return(func(result)); } var data = cache[_cacheKey] as IDictionary <string, T>; if (_cacheProvider is IPersistentCacheProviderEx <T> _cacheProviderWithDelta && savedLastChange != null && data != null) { var(replacedItemsIdentifiers, updatedItems, lastUpdate) = _cacheProviderWithDelta.GetDelta(savedLastChange); ApplyDelta(data, replacedItemsIdentifiers, updatedItems); SetCache(cache, lastUpdate); } else { data = _cacheProvider.GetAllCachedItems(); lastChange = _cacheProvider.LastChanged; SetCache(cache, data, lastChange); } return(func(data)); } finally { _cacheLock.ExitReadLock(); } }