alastairtree / LazyCache

An easy to use thread safe in-memory caching service with a simple developer friendly API for c#
https://nuget.org/packages/LazyCache
MIT License
1.72k stars 159 forks source link

Clear or loop #122

Closed scascalesageinfoes closed 4 years ago

scascalesageinfoes commented 4 years ago

Hello.

I found method to clear all cache: productCache.CacheProvider.Dispose(); (https://github.com/alastairtree/LazyCache/issues/6 where is ObjectCache object?)

but... what about loop existing keys ? I found this: https://stackoverflow.com/questions/8023543/can-i-iterate-over-the-net4-memorycache.

If i can get instanceIMemoryCache with this is possible:
https://github.com/alastairtree/LazyCache/issues/56 https://stackoverflow.com/questions/45597057/how-to-retrieve-a-list-of-memory-cache-keys-in-asp-net-core Implmentation for lazy?

Thx

alastairtree commented 4 years ago

You cannot iterate the keys in the underlying MemoryCache reliably because the list of keys and items are continually changing as items are added/removed/expire. The list is likely to change during iteration. It is also an expensive operation and is generally a code smell as there are usually ways to avoid the need to clear the entire cache.

But if you must clear everything see the docs https://github.com/alastairtree/LazyCache/wiki/API-documentation-(v-2.x)#empty-the-entire-cache

hitmanpc commented 3 years ago

If needed I ported a dll library over to .netstandard 2.0 (where lazy cache is utilized), but needed the keys within .net framework 4.7.2 web application.

within the .netstandard 2.0:

public static IEnumerable<ICacheEntry> GetAllCacheEntries()
        {

            var field = typeof(MemoryCacheProvider).GetField("cache", BindingFlags.NonPublic | BindingFlags.Instance);
            IMemoryCache cacheObj = field.GetValue(_Cache.CacheProvider) as MemoryCache;

            var cacheProperty = typeof(MemoryCache).GetProperty("EntriesCollection", BindingFlags.NonPublic | BindingFlags.Instance);
            var cacheCollection = (ICollection)cacheProperty.GetValue(cacheObj, null);

            foreach (var cacheItem in cacheCollection)
            {
                var valProp = cacheItem.GetType().GetProperty("Value");
                ICacheEntry cacheValue = (ICacheEntry)valProp.GetValue(cacheItem, null);

                yield return cacheValue;
            };

        }

Then call the GetAllCacheEntries method within your .net standard library from the framework application and loop through as needed.