Caching Data in Web API

前端 未结 2 1359
长情又很酷
长情又很酷 2020-12-01 02:13

I have the need to cache a collection of objects that is mostly static (might have changes 1x per day) that is avaliable in my ASP.NET Web API OData service. This result set

相关标签:
2条回答
  • 2020-12-01 02:39

    Yes, output caching is not what you are looking for. You can cache the data in memory with MemoryCache for example, http://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache.aspx . However, you will lose that data if the application pool gets recycled. Another option is to use a distributed cache like AppFabric Cache or MemCache to name a few.

    0 讨论(0)
  • 2020-12-01 02:44

    The solution I ended up using involved MemoryCache in the System.Runtime.Caching namespace. Here is the code that ended up working for caching my collection:

    //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;
    

    Here is another way I found using Lazy<T> to take into account locking and concurrency. Total credit goes to this post: How to deal with costly building operations using 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
    }
    
    0 讨论(0)
提交回复
热议问题