有什么办法清除/刷新/删除OutputCache?

时间:2009-02-19 13:07:09

标签: asp.net caching

我正在使用我的webuser控件(.ascx)上的OutputCache

<%@ OutputCache Duration="1000" VaryByParam="none" %>

我想在接下来的1000秒内保留缓存,但是当我的网站上的某个特定页面被加载时,我想删除/刷新/刷新缓存。就像,我想在加载MyPage.aspx时清除缓存。我可以用程序刷新缓存吗?

它只有一个页面是缓存,因此没有用于刷新缓存的paramatrized版本。

提前感谢您的帮助。

7 个答案:

答案 0 :(得分:33)

您可以使用VaryByCustom参数。

在您的用户控件中,您将拥有以下内容:

<%@ OutputCache Duration="1000" VaryByParam="None" VaryByCustom="MyKey" %>

然后你会覆盖Global.asax中的GetVaryByCustomString方法,如下所示:

public override string GetVaryByCustomString(HttpContext context, string arg)
{
    if (arg == "MyKey")
    {
        object o = context.Current.Application["MyGuid"];
        if (o == null)
        {
            o = Guid.NewGuid();
            context.Current.Application["MyGuid"] = o;
        }
        return o.ToString();
    }
    return base.GetVaryByCustomString(context, arg);
}

最后在MyPage.aspx你会这样做:

Application["MyGuid"] = Guid.NewGuid();

这是如何运作的?

每当您的控件被缓存时,它都与一个字符串相关联(当您的控件的GetVaryByCustomString键传递给它时,从VaryByCustom方法返回的字符串)。

每当随后使用该控件时,再次调用GetVaryByCustomString。如果返回的字符串与控件的缓存版本匹配,则使用缓存版本。

在我们的案例中,“MyKey”被传递到GetVaryByCustomString并返回Application["MyGuid"]中存储的内容。

每当调用MyPage.aspx时,它会将Application["MyGuid"]更改为新的随机值。

下次使用您的控件时,GetVaryByCustomString方法将返回新值,并且由于没有与该值关联的控件的缓存版本,因此将重新生成控件。 (然后控件将被缓存并与新值相关联,以持续到下一次调用MyPage.aspx等)

有一个概述here

答案 1 :(得分:11)

您可以使用HttpResponse.RemoveOutputCacheItemHttpResponse.AddCacheItemDependency使输出缓存条目无效。

答案 2 :(得分:8)

要破解一种坚定的方法,这是一个大锤,但它是完全清除/刷新我发现的应用程序缓存的最简单,最有效的方法。

只需致电:

HttpRuntime.UnloadAppDomain();

这与回收应用程序池具有相同的影响。不适合所有情况,但它肯定会完成工作。

答案 3 :(得分:4)

编辑:如果您在II6 +上启用了内核缓存,那么您需要使用Luke的建议并使用VaryByCustom标头,因为清除ASP.NET缓存不会影响内核缓存。

OutputCache存储在ASP.NET缓存中,因此您只需调用Cache.Remove:

即可
List<string> keys = new List<string>();

foreach(string key in HttpRuntime.Cache)
{
    keys.Add(key);
}

foreach(string key in keys)
{
    Cache.Remove(key);
}

但是,这将删除所有缓存条目,包括您的代码添加的自定义条目。

答案 4 :(得分:4)

通过在其他帖子中获取灵感,以下代码段使用反射成功删除了asp.net中OutputCache缓存的每个页面:

        public static void ClearOutputCache()
        {

            var runtimeType = typeof(HttpRuntime);

            var ci = runtimeType.GetProperty(
               "CacheInternal",
               BindingFlags.NonPublic | BindingFlags.Static);

            var cache = ci.GetValue(ci, new object[0]);

            var cachesInfo = cache.GetType().GetField(
                "_caches",
                BindingFlags.NonPublic | BindingFlags.Instance);
            var cacheEntries = cachesInfo.GetValue(cache);

            var outputCacheEntries = new List<object>();

            foreach (Object singleCache in cacheEntries as Array)
            {
                var singleCacheInfo =
                singleCache.GetType().GetField("_entries",
                   BindingFlags.NonPublic | BindingFlags.Instance);
                var entries = singleCacheInfo.GetValue(singleCache);

                foreach (DictionaryEntry cacheEntry in entries as Hashtable)
                {
                    var cacheEntryInfo = cacheEntry.Value.GetType().GetField("_value",
                       BindingFlags.NonPublic | BindingFlags.Instance);
                    var value = cacheEntryInfo.GetValue(cacheEntry.Value);
                    if (value.GetType().Name == "CachedRawResponse")
                    {
                        var key = (string)cacheEntry.Value.GetType().BaseType.GetField("_key", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(cacheEntry.Value);
                        key = key.Substring(key.IndexOf("/"));
                        outputCacheEntries.Add(key);
                    }
                }
            }
            foreach (string key in outputCacheEntries)
            {  
                HttpResponse.RemoveOutputCacheItem(key);
            }
        }

答案 5 :(得分:2)

你可以添加HttpResponse.RemoveOutputCacheItem(“/ YourCachePageName.aspx”);页面的页面加载事件中的代码行,加载您期望缓存页面的缓存关闭。

答案 6 :(得分:1)

由于this answer不再起作用,并且this answer仅清除自定义缓存项目(不清除存储在缓存中的页面/ MVC操作),我通过ASP.NET参考源代码进行了挖掘并提出了这个:

public static void ClearAllCache()
{
    var runtimeType = typeof(System.Web.Caching.Cache);

    var ci = runtimeType.GetProperty(
       "InternalCache",
       BindingFlags.Instance | BindingFlags.NonPublic);

    var cache = ci.GetValue(HttpRuntime.Cache) as System.Web.Caching.CacheStoreProvider;
    enumerator = cache.GetEnumerator();
    while (enumerator.MoveNext())
    {
        keys.Add(enumerator.Key.ToString());
    }
    foreach (string key in keys)
    {
        cache.Remove(key);
    }
}

我的博客文章here

中的更多信息