Я использую C # MemoryCache для сохранения некоторых элементов.
Вспомогательный класс для общей обработки хранилища элементов
public static class MemoryCacheHelper
{
public static T Get<T>(string key, object lockHandle)
{
lock (lockHandle)
{
return (T) MemoryCache.Default.Get(key);
}
}
public static T GetOrAdd<T>(string key, int seconds, object lockHandle, Func<T> factory, Action<CacheEntryUpdateArguments> onRemoveAction)
{
var cacheItemPolicy = new CacheItemPolicy
{
AbsoluteExpiration = DateTime.Now.AddSeconds(seconds),
UpdateCallback = args => onRemoveAction(args),
Priority = CacheItemPriority.NotRemovable
};
lock (lockHandle)
{
var existingObj = (T) MemoryCache.Default.Get(key);
if (existingObj != null)
return existingObj;
var newObj = factory.Invoke();
MemoryCache.Default.Set(key, newObj, cacheItemPolicy);
return newObj;
}
}
}
Пример использования
var ret = MemoryCacheHelper.GetOrAdd(sessionKey, SessionTime, ConnectionSessionSync,
factory: () => GetNewConnection(environmentId, token),
onRemoveAction: args =>
{
// does not work because UpdatedCacheItem is null
// var da = args.UpdatedCacheItem.Value as ITeradataDataAccess;
// works!
var da = MemoryCacheHelper.Get<ITeradataDataAccess>(sessionKey, ConnectionSessionSync);
da?.Dispose();
});
В соответствии с CacheItemPolicy документация UpdateCallback
вызывается до удаления элемента из кэша:
Получает или задает ссылку на делегат CacheEntryUpdateCallback, который вызывается перед кэшированием.запись удалена из кэша:
Получает или задает ссылку на делегат CacheEntryUpdateCallback, который вызывается перед удалением записи кэша из кэша.
Действительно, MemoryCache.Default.Get(key)
по-прежнему возвращаетправильная ссылка.
Однако я ожидал, что контекст в этом обратном вызове предоставит эту ссылку без необходимости извлекать ее из самого кэша (т. е. args.UpdatedCacheItem
).
Вопрос: Почему аргумент UpdateCallback
не обеспечивает удаление элемента?Я чувствую, что что-то не так с настройкой кэша.
Примечание: Мой проект нацелен на .NET Framework 4.5.2