How to remove all objects (reset) from IMemoryCache in ASP.NET core

I can find the remove method to remove an object from IMemoryCache by its key. Is there a way to reset the entire cache and delete all objects?

Edit:

How to clear MemoryCache? The Dispose method provided in the link gives me an exception in asp.net 5. ObjectDisposedException: Cannot access a disposed object. Object name: 'Microsoft.Extensions.Caching.Memory.MemoryCache'. ObjectDisposedException: Cannot access a disposed object. Object name: 'Microsoft.Extensions.Caching.Memory.MemoryCache'.

+17
c # asp.net-core asp.net-core-mvc
source share
5 answers

https://docs.microsoft.com/en-us/aspnet/core/performance/caching/memory Cache Dependencies Section

Using CancellationTokenSource allows you to delete multiple cache entries as a group.

This code worked for me:

 public class CacheProvider { private static CancellationTokenSource _resetCacheToken = new CancellationTokenSource(); private readonly IMemoryCache _innerCache; /* other methods and constructor removed for brevity */ public T Set<T>(object key, T value) { /* some other code removed for brevity */ var options = new MemoryCacheEntryOptions().SetPriority(CacheItemPriority.Normal).SetAbsoluteExpiration(typeExpiration); options.AddExpirationToken(new CancellationChangeToken(_resetCacheToken.Token)); _innerCache.Set(CreateKey(type, key), value, options); return value; } public void Reset() { if (_resetCacheToken != null && !_resetCacheToken.IsCancellationRequested && _resetCacheToken.Token.CanBeCanceled) { _resetCacheToken.Cancel(); _resetCacheToken.Dispose(); } _resetCacheToken = new CancellationTokenSource(); } } 
+18
source share

The answer to RC1 is that you cannot make it out of the box from what I read and said (I read on GitHub that there may be a way to create triggers to facilitate this, what happens),

You are currently provided with Get, Set, and Remove. I see your options as:

  • Create a cache manager wrapper that will keep track of all your keys, and then you can remove these items in bulk if you want. I'm not in love with this, but it will work. Of course, if you do not control the addition, there may be things in the cache that you do not know about (you could compare your score with it to see). If you click IMemoryCache as MemoryCache, you can get the public property Count.
  • Build and print the Keys and / or add a method for deleting these elements. There is a main dictionary containing keys. I did this, compiled it by creating a Nuget package for it, and then replaced the RC1 version to see if I could (and it worked). Not sure if this is the right way, but here is fixing my plug, I just added a read-only property, where I dumped the keys into the list of objects (keys are stored as objects). As in previous implementations of MemoryCache, if you opened the keys, they may be outdated after they were reset, but if you just use them to clear all, then it does not matter.

https://github.com/blakepell/Caching/commit/165ae5ec13cc51c44a6007d6b88bd9c567e1d724

I posted this issue last night, trying to figure out if there is a good way to check what exactly is in the cache (ask why we don’t have a way). If you don’t ask, you will never know if this matters, so I understood why not.

https://github.com/aspnet/Caching/issues/149

+2
source share

There are many hacks to do this. If you have the correct IMemoryCache, you can use Compact(1.0) , otherwise this hack works:

This code will work (tested in unit tests and in production on .NET core 2.2):

 PropertyInfo prop = cache.GetType().GetProperty("EntriesCollection", BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.Public); object innerCache = prop.GetValue(cache); MethodInfo clearMethod = innerCache.GetType().GetMethod("Clear", BindingFlags.Instance | BindingFlags.Public); clearMethod.Invoke(innerCache, null); 
+2
source share

My solution was to set a new expiration date for all items in the cache to be 1 millisecond. Then they expired and therefore clear the cache.

+1
source share

My solution was to create a wrapper that redisplays the existing multiple methods and adds the missing method, replacing the MemoryCache object with a new one. It worked just fine for me. Code below:

 public interface IMyMemoryCache : IMemoryCache { void Reset(); } public class MyMemoryCache: IMyMemoryCache { IMemoryCache _memoryCache; public MyMemoryCache() { Reset(); } public void Dispose() { _memoryCache.Dispose(); } public bool TryGetValue(object key, out object value) { return _memoryCache.TryGetValue(key, out value); } public ICacheEntry CreateEntry(object key) { return _memoryCache.CreateEntry(key); } public void Remove(object key) { _memoryCache.Remove(key); } public void Reset() { _memoryCache = new MemoryCache(new MemoryCacheOptions()); } } 
0
source share

All Articles