简体   繁体   English

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

[英]Any way to clear/flush/remove OutputCache?

I'm using the OutputCache on my webuser control (.ascx) 我在我的webuser控件(.ascx)上使用OutputCache

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

I would like to retain the cache for next 1000 seconds, but when a specific page on my site is loaded, I would like to remove/flush/refresh the cache. 我想在接下来的1000秒内保留缓存,但是当我的网站上的特定页面被加载时,我想删除/刷新/刷新缓存。 Like, I want to clear the cache when MyPage.aspx is loaded. 就像,我想在加载MyPage.aspx时清除缓存。 Can i flush the cache programmetically? 我可以在程序上刷新缓存吗?

Its only one page being cache so there are no paramatrized versions to flush cache with. 它只有一个页面是缓存,因此没有用于刷新缓存的paramatrized版本。

Thanks for your help in advance. 感谢您的帮助。

You can use the VaryByCustom parameter for this. 您可以使用VaryByCustom参数。

In your user control you would have the following: 在您的用户控件中,您将拥有以下内容:

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

Then you would override the GetVaryByCustomString method in your Global.asax like so: 然后你将覆盖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);
}

Finally in MyPage.aspx you would do this: 最后在MyPage.aspx你会这样做:

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

How does this work? 这是如何运作的?

Whenever your control is cached, it is associated with a string (the string returned from the GetVaryByCustomString method when your control's VaryByCustom key is passed into it). 每当您的控件被缓存时,它都与一个字符串相关联(当您的控件的VaryByCustom键传入其中时,从GetVaryByCustomString方法返回的字符串)。

Whenever the control is subsequently used, GetVaryByCustomString is called again. 无论何时使用该控件, GetVaryByCustomString再次调用GetVaryByCustomString If the returned string matches a cached version of the control, then the cached version is used. 如果返回的字符串与控件的缓存版本匹配,则使用缓存版本。

In our case, "MyKey" is passed into GetVaryByCustomString and it returns whatever is stored in Application["MyGuid"] . 在我们的例子中,“MyKey”被传递到GetVaryByCustomString并返回存储在Application["MyGuid"]

Whenever MyPage.aspx is called, it changes Application["MyGuid"] to a new random value. 每当MyPage.aspx ,它都会将Application["MyGuid"]更改为新的随机值。

When your control is next used the GetVaryByCustomString method will return the new value, and because there is no cached version of the control associated with that value, the control will be regenerated. 下次使用控件时, GetVaryByCustomString方法将返回新值,并且由于没有与该值关联的控件的缓存版本,因此将重新生成控件。 (The control will then be cached and associated with the new value, to persist until the next call to MyPage.aspx etc) (然后控件将被缓存并与新值相关联,以持续到下一次调用MyPage.aspx等)

There's an overview here . 这里有一个概述这里

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

It's a bit of a sledgehammer to crack a nut sort of approach but it was the simplest and most effective way to completely clear/flush the cache of an application that I found find. 破解一种坚定的方法是一个大锤,但它是完全清除/刷新我发现的应用程序缓存的最简单,最有效的方法。

Simply call: 只需致电:

HttpRuntime.UnloadAppDomain();

This has the same impact as recycling the app pool. 这与回收应用程序池具有相同的影响。 Not suitable in every situation but it will definitely get the job done. 不适合所有情况,但它肯定会完成工作。

By taking inspiration on other post, the following snippet removes successfully every page cached by OutputCache in asp.net by using reflection: 通过在其他帖子上获取灵感,以下代码段使用反射成功删除了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);
            }
        }

Edit: If you have enabled kernel caching on II6+ then you will need to go with Luke's advice and use a VaryByCustom header, as clearing ASP.NET cache will not affect kernel cache. 编辑:如果您在II6 +上启用了内核缓存,那么您将需要使用Luke的建议并使用VaryByCustom标头,因为清除ASP.NET缓存不会影响内核缓存。

OutputCache is stored in the ASP.NET Cache, so you can just call Cache.Remove: OutputCache存储在ASP.NET Cache中,因此您只需调用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);
}

This will, however, remove ALL cache entries, including custom entries added by your code. 但是,这将删除所有缓存条目,包括代码添加的自定义条目。

you can add HttpResponse.RemoveOutputCacheItem("/YourCachePageName.aspx"); 你可以添加HttpResponse.RemoveOutputCacheItem(“/ YourCachePageName.aspx”); line of code in the page load event of the page, loading of which you expect the cached page's cache to go off. 页面的页面加载事件中的代码行,加载您期望缓存页面的缓存关闭。

Sinсe this answer no longer works, and this answer only clears custom cache items (not the pages/MVC-actions stored in cache), I digged through ASP.NET reference source codes and came up with this: Sin 答案这个答案不再适用, 这个答案只清除自定义缓存项(而不是存储在缓存中的页面/ 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);
    }
}

More info in my blog post here 在我的博客文章更多信息点击这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM