Подтвердить что ты не робот

Кэширование данных в веб-интерфейсе

Мне нужно кэшировать коллекцию объектов, которая в основном статична (может иметь изменения 1 раз в день), которая доступна в моей службе ASP.NET Web API OData. Этот набор результатов используется во всех вызовах (что означает не специфический клиентский вызов), поэтому его необходимо кэшировать на уровне приложения.

Я сделал кучу поиска в кешировании в Web API, но все результаты были посвящены "кэшированию вывода". Это не то, что я ищу здесь. Я хочу кэшировать коллекцию "Люди" для повторного использования при последующих вызовах (может иметь скользящее окончание).

Мой вопрос в том, что, поскольку это все еще просто ASP.NET, я использую традиционные методы кэширования приложений для сохранения этой коллекции в памяти или что-то еще мне нужно сделать? Эта коллекция напрямую не возвращается пользователю, а скорее используется в качестве источника за кулисами для запросов OData через вызовы API. Для меня нет оснований выходить в базу данных при каждом вызове, чтобы получить точную информацию о каждом вызове. По истечении срока оно должно быть достаточно.

Кто-нибудь знает, как правильно кэшировать данные в этом сценарии?

4b9b3361

Ответ 1

Да, кэширование вывода - это не то, что вы ищете. Вы можете кэшировать данные в памяти с помощью MemoryCache, например http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.aspx. Однако вы потеряете эти данные, если пул приложений будет переработан. Другой вариант - использовать распределенный кеш, такой как AppFabric Cache или MemCache, чтобы назвать несколько.

Ответ 2

Решение я закончило использование MemoryCache в пространстве имен System.Runtime.Caching. Вот код, который закончился для кэширования моей коллекции:

//If the data exists in cache, pull it from there, otherwise make a call to database to get the data
ObjectCache cache = MemoryCache.Default;

var peopleData = cache.Get("PeopleData") as List<People>;
if (peopleData != null)
   return peopleData ;

peopleData = GetAllPeople();
CacheItemPolicy policy = new CacheItemPolicy {AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(30)};
cache.Add("PeopleData", peopleData, policy);
return peopleData;

Вот еще один способ, который я нашел, используя Lazy<T>, чтобы учесть блокировку и concurrency. Общий кредит идет на этот пост: Как бороться с дорогостоящими операциями здания с использованием MemoryCache?

private IEnumerable<TEntity> GetFromCache<TEntity>(string key, Func<IEnumerable<TEntity>> valueFactory) where TEntity : class 
{
    ObjectCache cache = MemoryCache.Default;
    var newValue = new Lazy<IEnumerable<TEntity>>(valueFactory);            
    CacheItemPolicy policy = new CacheItemPolicy { AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(30) };
    //The line below returns existing item or adds the new value if it doesn't exist
    var value = cache.AddOrGetExisting(key, newValue, policy) as Lazy<IEnumerable<TEntity>>;
    return (value ?? newValue).Value; // Lazy<T> handles the locking itself
}