Question

Is there a way to look through the cache for all objects in the cache? I'm dynamically creating objects and I need to periodically go through the list to purge out objects I'm no longer using.

Was it helpful?

Solution

Yes, you can either index based on the cache key, or you you can iterate over the contents:

For Each c In Cache
    ' Do something with c
Next
' Pardon  my VB syntax if it's wrong

OTHER TIPS

        var keysToClear = (from System.Collections.DictionaryEntry dict in HttpContext.Cache
                           let key = dict.Key.ToString()
                           where key.StartsWith("Something_")
                           select key).ToList();


        foreach (var key in keysToClear)
        {
            HttpContext.Cache.Remove(key);
        }

You can enumerate through the objects:

 System.Web.HttpContext.Current.Cache.GetEnumerator()

Here is a VB function to iterate through the Cache and return a DataTable representation.

Private Function CreateTableFromHash() As DataTable

    Dim dtSource As DataTable = New DataTable
    dtSource.Columns.Add("Key", System.Type.GetType("System.String"))
    dtSource.Columns.Add("Value", System.Type.GetType("System.String"))
    Dim htCache As Hashtable = CacheManager.GetHash()
    Dim item As DictionaryEntry

    If Not IsNothing(htCache) Then
        For Each item In htCache
            dtSource.Rows.Add(New Object() {item.Key.ToString, item.Value.ToString})
        Next
    End If

    Return dtSource

End Function

This may be a bit late, but I used the following code to easily iterate over all cache items and perform some custom logic for removal of cache items that contain a certain string in their names.

I have provided both versions of code in VB.Net as well as C#.

VB.Net Version

Dim cacheItemsToRemove As New List(Of String)()
Dim key As String = Nothing
'loop through all cache items
For Each c As DictionaryEntry In System.Web.HttpContext.Current.Cache
    key = DirectCast(c.Key, String)
    If key.Contains("prg") Then
        cacheItemsToRemove.Add(key)
    End If
Next
'remove the selected cache items
For Each k As var In cacheItemsToRemove
    System.Web.HttpContext.Current.Cache.Remove(k)
Next

C# Version

List<string> cacheItemsToRemove  = new List<string>();
string key = null;
//loop through all cache items
foreach (DictionaryEntry c in System.Web.HttpContext.Current.Cache)
    {
       key = (string)c.Key;
        if (key.Contains("prg"))
        {
            cacheItemsToRemove.Add(key);
        }
    }
//remove the selected cache items
foreach (var k in cacheItemsToRemove)
   {
       System.Web.HttpContext.Current.Cache.Remove(k);
   }

Since you potentially want to be removing items from the Cache object, it is not terribly convenient to iterate over it (as an IEnumerable), since this doesn't allow removal during the iteration process. However, given that you cannot access items by index, it is the only solution.

A bit of LINQ can however simplify the problem. Try something like the following:

var cache = HttpContext.Current.Cache;
var itemsToRemove = cache.Where(item => myPredicateHere).ToArray();
foreach (var item in itemsToRemove)
    cache.Remove(itemsToRemove.Key);

Note that each item in the iteration is of type DictionaryEntry.

Jeff, you should really look up dependencies for your cached items. That's the proper way of doing this. Logically group your cached data (items) and setup dependencies for your groups. This way when you need to expire the entire group you touch such common dependency and they're all gone.

I'm not sure I understand the List of Object part.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top