18

次のように単純なオブジェクトがキャッシュされています。

_myCache.Add(someKey, someObj, policy);

_myCacheとして宣言されている場所ObjectCache(ただし、DI as を介して注入されているMemoryCache.DefaultsomeObjは、追加しているオブジェクトでpolicyあり、CacheItemPolicy.

私がCacheItemPolicyこのようなものを持っている場合:

var policy = new CacheItemPolicy 
{ 
   Priority = CacheItemPriority.Default, 
   SlidingExpiration = TimeSpan.FromHours(1)
};

つまり、1 時間で有効期限が切れます。涼しい。

しかし、何が起こるかというと、1 時間後に不運な最初のユーザーがヒットを待たなければならないということです。

「期限切れの」イベント/デリゲートにフックして、キャッシュを手動で更新する方法はありますか?

の言及がありCacheEntryChangeMonitorますが、私の例でそれを利用する方法について意味のあるドコ/例が見つかりません。

PS。手動で使用CacheItemPriority.NotRemovableして期限切れにすることができることはわかっていますが、キャッシュされたデータが少し複雑すぎるため、現在の例ではそれを行うことができません (たとえば、コード内の 10 の異なる場所で「無効化」する必要があります)。

何か案は?

4

3 に答える 3

16

CacheItemPolicy呼び出されRemovedCallbackた には、タイプのプロパティがあります: CacheEntryRemovedCallback。彼らが標準のイベントルートに行かなかった理由はわかりませんが、それはあなたが必要とすることをするはずです.

http://msdn.microsoft.com/en-us/library/system.runtime.caching.cacheitempolicy.removedcallback.aspx

于 2011-10-05T04:45:35.677 に答える
5

遅ればせながら、CacheItemUpdate コールバックと CacheItemRemove コールバックの興味深い違いに気付きました。

http://msdn.microsoft.com/en-us/library/system.web.caching.cacheitemupdatereason.aspx

特にこのコメント:

CacheItemRemovedReason 列挙とは異なり、この列挙には Removed または Underused の値は含まれません。更新可能なキャッシュ アイテムは削除できないため、メモリを解放する必要がある場合でも、ASP.NET によって自動的に削除されることはありません。

于 2012-04-16T15:02:48.210 に答える
2

これは、CacheRemovedCallbackキャッシュの有効期限が切れたときにイベントを使用する私の方法です。

私は誰のために懸念を共有します。

public static void SetObjectToCache<T>(string cacheItemName, T obj, long expireTime)
        {
            ObjectCache cache = MemoryCache.Default;

            var cachedObject = (T)cache[cacheItemName];

            if (cachedObject != null)
            {
                // remove it
                cache.Remove(cacheItemName);
            }

            CacheItemPolicy policy = new CacheItemPolicy()
            {
                AbsoluteExpiration = DateTimeOffset.Now.AddMilliseconds(expireTime),
                RemovedCallback = new CacheEntryRemovedCallback(CacheRemovedCallback)
            };

            cachedObject = obj;
            cache.Set(cacheItemName, cachedObject, policy);
        }

public static void CacheRemovedCallback(CacheEntryRemovedArguments arguments)
            {
                var configServerIpAddress = Thread.CurrentPrincipal.ConfigurationServerIpAddress();
                long configId = Thread.CurrentPrincipal.ConfigurationId();
                int userId = Thread.CurrentPrincipal.UserId();
                var tagInfoService = new TagInfoService();
                string returnCode = string.Empty;

                if (arguments.CacheItem.Key.Contains("DatatableTags_"))
                {
                    // do what's needed
                    Task.Run(() =>
                    {
                    });
                }

            }
于 2019-08-14T05:14:01.613 に答える