Любой способ очистки/очистки/удаления OutputCache?
Я использую OutputCache для моего webuser-управления (.ascx)
<%@ OutputCache Duration="1000" VaryByParam="none" %>
Я хотел бы сохранить кеш в течение следующих 1000 секунд, но когда загружается конкретная страница на моем сайте, я хотел бы удалить/сбросить/обновить кеш. Например, я хочу очистить кеш при загрузке MyPage.aspx. Могу ли я выполнить кэширование программно?
Единственная одна страница - это кеш, поэтому нет параматеризированных версий для очистки кеша с помощью.
Спасибо за вашу помощь заранее.
Ответы
Ответ 1
Для этого вы можете использовать параметр VaryByCustom
.
В вашем пользовательском элементе управления вы должны иметь следующее:
<%@ OutputCache Duration="1000" VaryByParam="None" VaryByCustom="MyKey" %>
Затем вы переопределили метод GetVaryByCustomString
в своем Global.asax так:
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
и т.д.)
Вот обзор здесь.
Ответ 2
Вы можете использовать HttpResponse.RemoveOutputCacheItem
или HttpResponse.AddCacheItemDependency
для недействительности записей выходного кэша.
Ответ 3
Это немного кувалдой, чтобы взломать какой-то подход, но это был самый простой и эффективный способ полностью очистить/сбросить кеш приложения, которое я нашел.
Просто позвоните:
HttpRuntime.UnloadAppDomain();
Это оказывает такое же влияние, как и на повторное использование пула приложений. Не подходит в любой ситуации, но это определенно сделает работу.
Ответ 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);
}
Это, однако, удалит ВСЕ записи кэша, включая пользовательские записи, добавленные вашим кодом.
Ответ 5
Вдохновляясь другим сообщением, следующий фрагмент успешно удаляет каждую страницу, кэшированную OutputCache
в asp.net, используя отражение:
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);
}
}
Ответ 6
вы можете добавить HttpResponse.RemoveOutputCacheItem( "/YourCachePageName.aspx" ); строка кода в событии загрузки страницы на странице, загрузка которой вы ожидаете, что кеш-кеш-страница будет отключена.
Ответ 7
Так как этот ответ больше не работает, и этот ответ очищает только пользовательские элементы кэша (не страницы/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);
}
}
Больше информации в моем блоге здесь