Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I clear a System.Runtime.Caching.MemoryCache

I use a System.Runtime.Caching.MemoryCache to hold items which never expire. However, at times I need the ability to clear the entire cache. How do I do that?

I asked a similar question here concerning whether I could enumerate the cache, but that is a bad idea as it needs to be synchronised during enumeration.

I've tried using .Trim(100) but that doesn't work at all.

I've tried getting a list of all the keys via Linq, but then I'm back where I started because evicting items one-by-one can easily lead to race conditions.

I thought to store all the keys, and then issue a .Remove(key) for each one, but there is an implied race condition there too, so I'd need to lock access to the list of keys, and things get messy again.

I then thought that I should be able to call .Dispose() on the entire cache, but I'm not sure if this is the best approach, due to the way it's implemented.

Using ChangeMonitors is not an option for my design, and is unnecassarily complex for such a trivial requirement.

So, how do I completely clear the cache?

like image 529
Peter Marks Avatar asked Nov 07 '11 22:11

Peter Marks


People also ask

How do I clear my MemoryCache default?

You can dispose the MemoryCache. Default cache and then re-set the private field singleton to null, to make it recreate the MemoryCache. Default.

Should I dispose MemoryCache?

MemoryCache implements IDisposable so you should call Dispose before replacing the old instance.

Where is MemoryCache stored?

Cache memory increases a computer's performance. The cache memory is located very close to the CPU, either on the CPU chip itself or on the motherboard in the immediate vicinity of the CPU and connected by a dedicated data bus.


2 Answers

I was struggling with this at first. MemoryCache.Default.Trim(100) does not work (as discussed). Trim is a best attempt, so if there are 100 items in the cache, and you call Trim(100) it will remove the ones least used.

Trim returns the count of items removed, and most people expect that to remove all items.

This code removes all items from MemoryCache for me in my xUnit tests with MemoryCache.Default. MemoryCache.Default is the default Region.

foreach (var element in MemoryCache.Default) {     MemoryCache.Default.Remove(element.Key); } 
like image 169
Alexander Williamson Avatar answered Sep 24 '22 14:09

Alexander Williamson


You should not call dispose on the Default member of the MemoryCache if you want to be able to use it anymore:

The state of the cache is set to indicate that the cache is disposed. Any attempt to call public caching methods that change the state of the cache, such as methods that add, remove, or retrieve cache entries, might cause unexpected behavior. For example, if you call the Set method after the cache is disposed, a no-op error occurs. If you attempt to retrieve items from the cache, the Get method will always return Nothing. http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.dispose.aspx

About the Trim, it's supposed to work:

The Trim property first removes entries that have exceeded either an absolute or sliding expiration. Any callbacks that are registered for items that are removed will be passed a removed reason of Expired.

If removing expired entries is insufficient to reach the specified trim percentage, additional entries will be removed from the cache based on a least-recently used (LRU) algorithm until the requested trim percentage is reached.

But two other users reported it doesnt work on same page so I guess you are stuck with Remove() http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.trim.aspx

Update However I see no mention of it being singleton or otherwise unsafe to have multiple instances so you should be able to overwrite your reference.

But if you need to free the memory from the Default instance you will have to clear it manually or destroy it permanently via dispose (rendering it unusable).

Based on your question you could make your own singleton-imposing class returning a Memorycache you may internally dispose at will.. Being the nature of a cache :-)

like image 39
stefan Avatar answered Sep 26 '22 14:09

stefan