web-dev-qa-db-ja.com

OutputCacheをクリア/フラッシュ/削除する方法はありますか?

Webユーザーコントロール(.ascx)でOutputCacheを使用しています

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

次の1000秒間キャッシュを保持したいのですが、サイトの特定のページが読み込まれたときに、キャッシュを削除/フラッシュ/更新したいと思います。同様に、MyPage.aspxがロードされたときにキャッシュをクリアしたいと思います。プログラムでキャッシュをフラッシュできますか?

キャッシュされているのは1ページだけなので、キャッシュをフラッシュするためのパラメーター化されたバージョンはありません。

よろしくお願いします。

28
Raheel Khokhar

これには 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などの呼び出しまで保持されます)

概要があります ここ

33
LukeH

HttpResponse.RemoveOutputCacheItem または HttpResponse.AddCacheItemDependency 出力キャッシュエントリを無効にします。

11
Josef Pfleger

ちょっとしたアプローチを破るのはちょっとした大ハンマーですが、私が見つけたアプリケーションのキャッシュを完全にクリア/フラッシュするための最も簡単で効果的な方法でした。

単に電話してください:

HttpRuntime.UnloadAppDomain();

これは、アプリプールのリサイクルと同じ影響があります。すべての状況に適しているわけではありませんが、それは間違いなく仕事を成し遂げます。

8
Tom Styles

編集: 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);
}

ただし、これにより、コードによって追加されたカスタムエントリを含む、すべてのキャッシュエントリが削除されます。

4
Richard Szalay

次のスニペットは、他の投稿からインスピレーションを得て、リフレクションを使用して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);
            }
        }
4
ʞᴉɯ

httpResponse.RemoveOutputCacheItem( "/ YourCachePageName.aspx");を追加できます。ページのページロードイベントのコード行。キャッシュされたページのキャッシュがオフになると予想されるロード。

2
suranga

この回答 機能しなくなり、 この回答 カスタムキャッシュアイテムのみをクリアします(キャッシュに格納されているページ/ 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);
    }
}

私のブログ投稿の詳細情報 ここ

1
Alex