有啥方法可以清除/刷新/删除OutputCache?
Posted
技术标签:
【中文标题】有啥方法可以清除/刷新/删除OutputCache?【英文标题】:Any way to clear/flush/remove OutputCache?有什么方法可以清除/刷新/删除OutputCache? 【发布时间】:2009-02-19 13:07:08 【问题描述】:我在我的网络用户控件 (.ascx) 上使用 OutputCache
<%@ OutputCache Duration="1000" VaryByParam="none" %>
我想在接下来的 1000 秒内保留缓存,但是当我网站上的特定页面被加载时,我想删除/刷新/刷新缓存。比如,我想在加载 MyPage.aspx 时清除缓存。我可以通过编程方式刷新缓存吗?
它只有一页被缓存,因此没有参数化版本可以刷新缓存。
提前感谢您的帮助。
【问题讨论】:
【参考方案1】:您可以为此使用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();
这是如何工作的?
当你的控件被缓存时,它与一个字符串相关联(当你的控件的VaryByCustom
键被传递给它时,从GetVaryByCustomString
方法返回的字符串)。
每当随后使用该控件时,都会再次调用GetVaryByCustomString
。如果返回的字符串与控件的缓存版本匹配,则使用缓存版本。
在我们的例子中,“MyKey”被传递到GetVaryByCustomString
并返回存储在Application["MyGuid"]
中的任何内容。
每当调用MyPage.aspx
时,它都会将Application["MyGuid"]
更改为一个新的随机值。
下次使用您的控件时,GetVaryByCustomString
方法将返回新值,并且由于没有与该值关联的控件的缓存版本,因此将重新生成控件。 (然后控件将被缓存并与新值相关联,直到下一次调用 MyPage.aspx
等)
有一个概述here。
【讨论】:
是删除之前的副本还是保留2个? 这实际上并没有从缓存中清除任何东西,只是添加了一个新的唯一键,看起来像是一个清除缓存,所以是的,现在内存中会有两个缓存数据的副本。如果您已经在网站的其他地方使用 VaryByCustom,您可能需要修改上述代码以将 GUID 附加到现有的 VaryByCustom 字符串。 此方法成功。感谢您的提示。干得好。【参考方案2】:您可以使用HttpResponse.RemoveOutputCacheItem
或HttpResponse.AddCacheItemDependency
使输出缓存条目无效。
【讨论】:
我最终做了类似的事情:***.com/questions/11585/… 如果您的 OutputCacheProvider 不是默认值(例如,您使用的是 AppFabric 或 MemCached)这些方法将不起作用。只是提醒任何考虑他们的选择的人......我认为 VaryByCustom 答案更可取,因为它适用于任何一种情况。 真的两者都可取; VaryByCustom 可以为您提供他所询问的一些内容,但如果页面的先前版本真的永远死了,再也不会被使用,您可能会通过使用 RemoveOutputCacheItem 显式驱逐它来减少缓存压力。【参考方案3】:破解一种疯狂的方法有点像大锤,但它是完全清除/刷新我发现的应用程序缓存的最简单和最有效的方法。
只需调用:
HttpRuntime.UnloadAppDomain();
这与回收应用程序池具有相同的影响。并非在所有情况下都适用,但它肯定会完成工作。
【讨论】:
我同意。在用尽了许多不同的技术之后,这是唯一可靠的工作方法。 这根本不是清除缓存的唯一可靠方法。这意味着其他机制都不起作用,这是大胆的。卸载应用程序域非常繁琐。【参考方案4】:编辑:如果您在 II6+ 上启用了内核缓存,那么您将需要遵循 Luke 的建议并使用 VaryByCustom 标头,因为清除 ASP.NET 缓存不会影响内核缓存。
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);
但是,这将删除所有缓存条目,包括您的代码添加的自定义条目。
【讨论】:
你确定这是同一个缓存吗?我认为 OutputCache 是 IIS 的东西。我认为这行不通。 在 IIS7 中默认启用内核缓存:technet.microsoft.com/en-us/library/cc731903(v=ws.10).aspx 因此,如果您从未配置过此功能,则已启用它。 这只会删除自定义缓存项目,而不是缓存的网址/页面。【参考方案5】:受其他帖子的启发,下面的 sn-p 使用反射成功删除了 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);
【讨论】:
这个答案对我帮助很大。能够遍历缓存并获取密钥向我展示了我所需要的。谢谢。 我尝试使用代码,但出现运行时错误 System.NullReferenceException: var cacheEntries = cachesInfo.GetValue(cache);【参考方案6】:由于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
【讨论】:
【参考方案7】:您可以添加 HttpResponse.RemoveOutputCacheItem("/YourCachePageName.aspx");页面的页面加载事件中的代码行,您希望缓存页面的缓存关闭。
【讨论】:
以上是关于有啥方法可以清除/刷新/删除OutputCache?的主要内容,如果未能解决你的问题,请参考以下文章
IIS(动态和静态)缓存、OutPutCache 和浏览器缓存有啥区别