.NET 4 ObjectCache - Можем ли мы подключиться к событию "Срок действия кэша истек"?

У меня есть простой объект, который кэшируется следующим образом:

_myCache.Add(someKey, someObj, policy);

куда _myCache объявлен как ObjectCache (но вводится через DI как MemoryCache.Default), someObj это объект, который я добавляю, и policy это CacheItemPolicy,

Если у меня есть CacheItemPolicy как это:

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

Это означает, что истекает через 1 час. Здорово.

Но что случится, так это то, что незадачливому первому пользователю через час придется ждать попадания.

Есть ли способ, которым я могу подключиться к "просроченному" событию / делегату и вручную обновить кеш?

Я вижу, что есть упоминание о CacheEntryChangeMonitor но я не могу найти никаких значимых документов / примеров о том, как использовать его в моем примере.

PS. Я знаю, что могу использовать CacheItemPriority.NotRemovable и истекает это вручную, но я не могу сделать это в моем текущем примере, потому что кэшированные данные слишком сложны (например, мне нужно было бы "сделать недействительными" примерно в 10 разных местах в моем коде).

Есть идеи?

2 ответа

Решение

Есть собственность на CacheItemPolicy называется RemovedCallback который имеет тип: CacheEntryRemovedCallback, Не уверен, почему они не пошли по стандартному маршруту, но это должно делать то, что вам нужно.

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

Позднее с этим, но я только что заметил интересную разницу между обратными вызовами CacheItemUpdate и CacheItemRemove.

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

В частности этот комментарий:

В отличие от перечисления CacheItemRemovedReason, это перечисление не включает значения Removed или Underused. Обновляемые элементы кэша не удаляются и, следовательно, никогда не могут автоматически удаляться ASP.NET, даже если есть необходимость освободить память.

Это мой способ использования 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(() =>
                    {
                    });
                }

            }
Другие вопросы по тегам