#c# #caching #.net-4.0 #objectcache
#c# #кэширование #.net-4.0 #ObjectCache
Вопрос:
У меня есть простой объект, который кэшируется следующим образом:
_myCache.Add(someKey, someObj, policy);
Where _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 разных местах моего кода).
Есть идеи?
Комментарии:
1. кстати, нет необходимости устанавливать Priority = CacheItemPriority . По умолчанию, поскольку это значение по умолчанию установлено по умолчанию 🙂
Ответ №1:
Для CacheItemPolicy
вызываемого свойства есть свойство RemovedCallback
типа: CacheEntryRemovedCallback
. Не уверен, почему они не пошли по стандартному маршруту событий, но это должно сделать то, что вам нужно.
http://msdn.microsoft.com/en-us/library/system.runtime.caching.cacheitempolicy.removedcallback.aspx
Комментарии:
1. Ну, ссылка не содержит примера кода — на самом деле в MSDN очень мало примеров кода для кэширования во время выполнения. В конце концов я понял это, но вы могли бы сэкономить мне час, предоставив пример.
2. Пример CodeProject «Использование кэша памяти в .NET 4.0»
Ответ №2:
Опоздал на вечеринку с этим, но я только что заметил интересное различие между обратными вызовами CacheItemUpdate и CacheItemRemove.
http://msdn.microsoft.com/en-us/library/system.web.caching.cacheitemupdatereason.aspx
В частности, этот комментарий:
В отличие от перечисления CacheItemRemovedReason, это перечисление не включает удаленные или недостаточно используемые значения. Обновляемые элементы кэша не являются съемными и, следовательно, никогда не могут быть автоматически удалены ASP.NET даже если есть необходимость освободить память.
Комментарии:
1. Даже позже для вечеринки, но я только что заметил, что вы ссылаетесь на типы в
System.Web.Caching
пространстве имен, в то время как вопрос касаетсяSystem.Runtime.Caching
пространства имен.2. @StevenLiekens, они перенесли кэширование в систему. Время выполнения в .NET 4, поскольку это было весьма полезно
3. Вы все еще можете использовать
System.Web.Caching
в .NET 4 и выше.
Ответ №3:
Это мой способ использовать CacheRemovedCallback
событие, когда срок действия кэша истек.
Я разделяю озабоченность по поводу кого.
public static void SetObjectToCache<T>(string cacheItemName, T obj, long expireTime)
{
ObjectCache cache = MemoryCache.Defau<
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(() =>
{
});
}
}