Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I iterate over the .NET4 MemoryCache?

I'm using the cache provided by System.Runtime.Caching.MemoryCache.

I'd like to enumerate over the cache's items so that I can invalidate (evict then reload) items as such

foreach (var item in MemoryCache.Default) { item.invalidate() }

But the official docs found here state:

!Important: Retrieving an enumerator for a MemoryCache instance is a resource-intensive and blocking operation. Therefore, the enumerator should not be used in production applications.

Surely there must be a simple and efficient way to iterate over the cache's items?

like image 492
Peter Marks Avatar asked Nov 05 '11 21:11

Peter Marks


People also ask

Is MemoryCache per user?

The ASP.NET Session object is per user key/value storage, whereas MemoryCache is an application level key/value storage (values are shared among all users).

Is MemoryCache a singleton?

Note that the MemoryCache is a singleton, but within the process. It is not (yet) a DistributedCache. Also note that Caching is Complex(tm) and that thousands of pages have been written about caching by smart people. This is a blog post as part of a series, so use your head and do your research.

Is MemoryCache shared?

MemoryCache does not allow you to share memory between processes as the memory used to cache objects is bound to the application pool. That's the nature of any in-memory cache implementation you'll find. The only way to actually use a shared cache is to use a distributed cache.

Is MemoryCache set thread safe?

MemoryCache is threadsafe. Multiple concurrent threads can read and write a MemoryCache instance. Internally thread-safety is automatically handled to ensure the cache is updated in a consistent manner.


2 Answers

Suggestions made so far have been great, but my need is still as stated: to iterate over the cache's items. It seems like such a simple task, and I expect that the cache internally has some sort of list structure anyway. The docs and the feature set for MemoryCache are wanting.

So as discussed above, I've added a list to my cache adapter class, which holds a reference to each item I place in the cache. If I need to iterate over the cache--not just for invalidation, but for gathering statistics, etc.--then I iterate over my list.

If the number of items placed in the cache does not change, then this is a reasonable solution. If the number does change, then you need to insert/remove via the adapter class, so as to keep the list in sync with the actual cache. Messy but it works, and avoids the perf penalties alluded to in the docs.

Hopefully MemoryCache cache provider will be fleshed-out in the next platform release.

like image 90
Peter Marks Avatar answered Sep 24 '22 06:09

Peter Marks


Consider using ChangeMonitors, which allow you to automatically evict stale entries when certain conditions are met.

See Is there some sort of CacheDependency in System.Runtime.Caching?

This is similar to System.Web.Caching CacheDependencys, who allow you to evict entries when files or other cache entries change.

like image 32
Will Avatar answered Sep 22 '22 06:09

Will