Webユーザーコントロール(.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();
これはどのように機能しますか?
コントロールがキャッシュされるたびに、文字列(コントロールのGetVaryByCustomString
キーが渡されたときにVaryByCustom
メソッドから返される文字列)に関連付けられます。
その後、コントロールが使用されるたびに、GetVaryByCustomString
が再度呼び出されます。返された文字列がコントロールのキャッシュされたバージョンと一致する場合、キャッシュされたバージョンが使用されます。
この場合、「MyKey」はGetVaryByCustomString
に渡され、Application["MyGuid"]
に格納されているものをすべて返します。
MyPage.aspx
が呼び出されるたびに、Application["MyGuid"]
が新しいランダムな値に変更されます。
次にコントロールを使用すると、GetVaryByCustomString
メソッドが新しい値を返します。その値に関連付けられたコントロールのキャッシュバージョンがないため、コントロールが再生成されます。 (その後、コントロールはキャッシュされ、新しい値に関連付けられ、次のMyPage.aspx
などの呼び出しまで保持されます)
概要があります ここ 。
HttpResponse.RemoveOutputCacheItem
または HttpResponse.AddCacheItemDependency
出力キャッシュエントリを無効にします。
ちょっとしたアプローチを破るのはちょっとした大ハンマーですが、私が見つけたアプリケーションのキャッシュを完全にクリア/フラッシュするための最も簡単で効果的な方法でした。
単に電話してください:
HttpRuntime.UnloadAppDomain();
これは、アプリプールのリサイクルと同じ影響があります。すべての状況に適しているわけではありませんが、それは間違いなく仕事を成し遂げます。
編集: II6 +でカーネルキャッシュを有効にしている場合は、ASP.NETキャッシュをクリアしてもカーネルキャッシュに影響しないため、Lukeのアドバイスに従ってVaryByCustomヘッダーを使用する必要があります。
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);
}
ただし、これにより、コードによって追加されたカスタムエントリを含む、すべてのキャッシュエントリが削除されます。
次のスニペットは、他の投稿からインスピレーションを得て、リフレクションを使用して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);
}
}
httpResponse.RemoveOutputCacheItem( "/ YourCachePageName.aspx");を追加できます。ページのページロードイベントのコード行。キャッシュされたページのキャッシュがオフになると予想されるロード。
罪 この回答 機能しなくなり、 この回答 カスタムキャッシュアイテムのみをクリアします(キャッシュに格納されているページ/ 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);
}
}
私のブログ投稿の詳細情報 ここ