ashes999
ashes999

Reputation: 10163

Cache Shows Old Values on IIS7, not Debug Server

I have a pretty standard MVC3 application. I'm trying to store some data that's application-wide (not user wide) in a the cache (in this case, a Theme object/name). When debugging (on the development server that integrates with Visual Studio), if I call SwitchTheme, I see the new theme right away. On IIS7, whatever theme was cached, stays cached; it doesn't update to the new theme.

Edit: Some code:

    public static Theme CurrentTheme { get {
        Theme currentTheme = HttpContext.Current.Cache[CURRENT_THEME] as Theme;

        if (currentTheme == null)
        {
            string themeName = DEFAULT_THEME;
            try
            {
                WebsiteSetting ws = WebsiteSetting.First(w => w.Key == WebsiteSetting.CURRENT_THEME);

                if (ws != null && !string.IsNullOrEmpty(ws.Value))
                {
                    themeName = ws.Value;
                }
            }
            catch (Exception e)
            {
                // DB not inited, or we're installing, or something broke.
                // Don't panic, just use the default.
            }

            // Sets HttpContext.Current.Cache[CURRENT_THEME] = new themeName)
            Theme.SwitchTo(themeName);
            currentTheme = HttpContext.Current.Cache[CURRENT_THEME] as Theme;

        }

        return currentTheme;
    } }

public static void SwitchTo(string name)
    {
        HttpContext.Current.Cache.Insert(CURRENT_THEME, new Theme(name), null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(30));

        // Persist change to the DB.
        // But don't do this if we didn't install the application yet.
        try
        {
            WebsiteSetting themeSetting = WebsiteSetting.First(w => w.Key == WebsiteSetting.CURRENT_THEME);
            if (themeSetting != null)
            {
                themeSetting.Value = name;
                themeSetting.Save();
            }
            // No "else"; if it's not there, we're installing, or Health Check will take care of it.
        }
        catch (Exception e)
        {
            // DB not inited or install not complete. No worries, mate.
        }
    }

I'm not sure where the problem is. I am calling the same method and updating the cache; but IIS7 just shows me the old version.

I can disable output caching in IIS, but that's not what I want to do. That seems like a hacky work-around at best.

Upvotes: 2

Views: 810

Answers (3)

ashes999
ashes999

Reputation: 10163

Given that this only happens on IIS7 when Output Caching is not disabled, this seems very likely to be an IIS7 bug. Seriously.

Whether it is or not, is irrelevant to the solution. What you need to do is find some manual process of invalidating the cache, such as touching the web.config file.

But beware: doing this will wipe out the cache (as you expect), but also all static variables (as a side-effect). Whether this is another bug or not, I don't know; but in my case, this was sufficient to solve the problem.

Upvotes: 0

kprobst
kprobst

Reputation: 16651

The HTTP cache is reset only if you do so manually or the app domain (or app pool) resets for whatever reason. Are you sure that's not happening in this case? And generally speaking, any global static variables would also be maintained in memory under the same circumstances.

There are many reasons why an app pool might be reset at any given point, such as a change to a web.config file, etc. I suggest checking that's not happening in your case.

By the way, output caching is a different thing, although it is maintained in memory largely the same way.

Upvotes: 1

Justin Helgerson
Justin Helgerson

Reputation: 25551

Without a code sample it's difficult to know what your problem is. In an attempt to provide some assistance, here is how I frequently set the cache in my applications:

    public static void SetCache(string key, object value) {
        if (value != null) {
            HttpRuntime.Cache.Insert(key, value, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(30));
        }
    }

Upvotes: 1

Related Questions