How to clear MemoryCache?

I created a cache using the MemoryCache class. I am adding some elements to it, but when I need to reload the cache, I want to clear it first. What is the fastest way to do this? Should I iterate over all the elements and delete them one by one or is there a better way?

+72
c # caching memory memorycache
Nov 15 '10 at 10:05
source share
9 answers

Dispose existing MemoryCache and create a new MemoryCache object.

+46
Nov 15 '10 at 10:12
source share

Listing Problem

The MemoryCache.GetEnumerator () block warns: "Retrieving an enumerator for an instance of MemoryCache is a resource-intensive and blocking operation. The enumerator should not be used in production applications."

This is why , explained in the pseudo code of the GetEnumerator () implementation:

 Create a new Dictionary object (let call it AllCache) For Each per-processor segment in the cache (one Dictionary object per processor) { Lock the segment/Dictionary (using lock construct) Iterate through the segment/Dictionary and add each name/value pair one-by-one to the AllCache Dictionary (using references to the original MemoryCacheKey and MemoryCacheEntry objects) } Create and return an enumerator on the AllCache Dictionary 

Since the implementation breaks the cache into several Dictionary objects, it must put everything together into one collection to pass a counter. Each call to GetEnumerator performs the complete copy process described above. The newly created dictionary contains references to the original internal key and value objects, so your actual cached data values ​​are not duplicated.

The warning in the documentation is correct. Avoid GetEnumerator () - including all the answers above that use LINQ queries.

The best and most flexible solution

Here's an effective way to clear the cache, which simply builds on your existing change monitoring infrastructure. It also provides the flexibility to clear either the entire cache or just a named subset and does not have any of the problems discussed above.

 // By Thomas F. Abraham (http://www.tfabraham.com) namespace CacheTest { using System; using System.Diagnostics; using System.Globalization; using System.Runtime.Caching; public class SignaledChangeEventArgs : EventArgs { public string Name { get; private set; } public SignaledChangeEventArgs(string name = null) { this.Name = name; } } /// <summary> /// Cache change monitor that allows an app to fire a change notification /// to all associated cache items. /// </summary> public class SignaledChangeMonitor : ChangeMonitor { // Shared across all SignaledChangeMonitors in the AppDomain private static event EventHandler<SignaledChangeEventArgs> Signaled; private string _name; private string _uniqueId = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture); public override string UniqueId { get { return _uniqueId; } } public SignaledChangeMonitor(string name = null) { _name = name; // Register instance with the shared event SignaledChangeMonitor.Signaled += OnSignalRaised; base.InitializationComplete(); } public static void Signal(string name = null) { if (Signaled != null) { // Raise shared event to notify all subscribers Signaled(null, new SignaledChangeEventArgs(name)); } } protected override void Dispose(bool disposing) { SignaledChangeMonitor.Signaled -= OnSignalRaised; } private void OnSignalRaised(object sender, SignaledChangeEventArgs e) { if (string.IsNullOrWhiteSpace(e.Name) || string.Compare(e.Name, _name, true) == 0) { Debug.WriteLine( _uniqueId + " notifying cache of change.", "SignaledChangeMonitor"); // Cache objects are obligated to remove entry upon change notification. base.OnChanged(null); } } } public static class CacheTester { public static void TestCache() { MemoryCache cache = MemoryCache.Default; // Add data to cache for (int idx = 0; idx < 50; idx++) { cache.Add("Key" + idx.ToString(), "Value" + idx.ToString(), GetPolicy(idx)); } // Flush cached items associated with "NamedData" change monitors SignaledChangeMonitor.Signal("NamedData"); // Flush all cached items SignaledChangeMonitor.Signal(); } private static CacheItemPolicy GetPolicy(int idx) { string name = (idx % 2 == 0) ? null : "NamedData"; CacheItemPolicy cip = new CacheItemPolicy(); cip.AbsoluteExpiration = System.DateTimeOffset.UtcNow.AddHours(1); cip.ChangeMonitors.Add(new SignaledChangeMonitor(name)); return cip; } } } 
+47
Mar 13 '14 at 19:26
source share

From http://connect.microsoft.com/VisualStudio/feedback/details/723620/memorycache-class-needs-a-clear-method

Workaround:

 List<string> cacheKeys = MemoryCache.Default.Select(kvp => kvp.Key).ToList(); foreach (string cacheKey in cacheKeys) { MemoryCache.Default.Remove(cacheKey); } 
+25
Feb 29 '12 at 14:00
source share
 var cacheItems = cache.ToList(); foreach (KeyValuePair<String, Object> a in cacheItems) { cache.Remove(a.Key); } 
+18
Sep 07 '11 at 12:45
source share

If performance is not a problem, this nice single-line file will do the trick:

 cache.ToList().ForEach(a => cache.Remove(a.Key)); 
+8
Dec 29 '13 at 1:35
source share

There seems to be a Trim method.

So, to clear all the content you just made

 cache.Trim(100) 

EDIT: after digging a little more, it seems that watching Trim is not worth your time

https://connect.microsoft.com/VisualStudio/feedback/details/831755/memorycache-trim-method-doesnt-evict-100-of-the-items

How to clear System.Runtime.Caching.MemoryCache

+6
Apr 11 '14 at 9:12
source share

You can also do something like this:

 Dim _Qry = (From n In CacheObject.AsParallel() Select n).ToList() For Each i In _Qry CacheObject.Remove(i.Key) Next 
+3
Jul 13 2018-11-11T00:
source share

Having gone through this and based on it, I wrote a slightly more efficient, transparent method:

  public void ClearAll() { var allKeys = _cache.Select(o => o.Key); Parallel.ForEach(allKeys, key => _cache.Remove(key)); } 
+2
Jul 18 '14 at 5:42
source share

slightly improved version of magritte's answer.

 var cacheKeys = MemoryCache.Default.Where(kvp.Value is MyType).Select(kvp => kvp.Key).ToList(); foreach (string cacheKey in cacheKeys) { MemoryCache.Default.Remove(cacheKey); } 
0
Oct 30 '13 at 20:08 on
source share



All Articles