.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(() =>
{
});
}
}