views:

965

answers:

1

I've created my own cache manager for a web site I'm developing and I was looking to find the best way to clear the cache under certain circumstances.

I found many articles saying the proper way to clear the cache is to call HttpRuntime.Close()

However, in my unit tests setup I call the encapsulated function HttpRuntime.Close() and the cache is NOT being cleared out.

I expected it to perform something similar to

foreach (DictionaryEntry cacheItem in HttpRuntime.Cache)
{
    HttpRuntime.Cache.Remove(cacheItem.Key.ToString());
}

The foreach loop works great in my encapsulated function, but the Close() never works right.

Am I misunderstanding the purpose of HttpRuntime.Close() or is there something more sinister going on here?

+2  A: 

Don't use Close, it does more than the docs say. And the docs also say not to use it while processing normal requests...

This is the reflected source of Close():

[SecurityPermission(SecurityAction.Demand, Unrestricted=true)]
public static void Close() {
    if (_theRuntime.InitiateShutdownOnce()) {
        SetShutdownReason(ApplicationShutdownReason.HttpRuntimeClose, "HttpRuntime.Close is called");
        if (HostingEnvironment.IsHosted) {
            HostingEnvironment.InitiateShutdown();
        } else {
            _theRuntime.Dispose();
        }
    }
}

Also, you cannot iterate over a collection and remove items from it at the same time, as this renders the enumeration invalid.

List<string> toRemove = new List<string>();
foreach (DictionaryEntry cacheItem in HttpRuntime.Cache) {
    toRemove.Add(cacheItem.Key.ToString());
}
foreach (string key in toRemove) {
    HttpRuntime.Cache.Remove(key);
}

But you should try to use cache dependencies to have the invalid cache entries cleared automatically for you...

Lucero
Actually I've already tested the code I put in my question and it works fine. I understand the issue with enumeration but for some reason the Cache doesn't seem to have a problem removing an item while walking through the list.
Joseph
That's not really my question though. What I'm saying is, if I have 4 items in the Cache, and I loop through it the way I've described, the Cache ends up with 0 items. However, when I use Close(), the 4 items are still there.
Joseph
That's because the docs state something which is not the full truth. Close() is not meant to be used to clear the cache.
Lucero
Ouch, ok thanks for the heads up on that. What do you mean by cache dependencies?
Joseph
When entries are added to the cache, you can give them dependencies like timeout, a file, another cached entry etc., which will clear out the cache item if this dependency triggers. See also http://msdn.microsoft.com/en-us/library/system.web.caching.cachedependency.aspx
Lucero
Oh I see, thanks Lucero!
Joseph