到期缓存的最佳方式

时间:2014-09-02 16:29:19

标签: asp.net caching global-asax

这是检索所有类别的代码,效果很好:

public static List<Category> GetAllCategories()
{
    var context = HttpContext.Current;
    var profiler = MiniProfiler.Current;
    using (profiler.Step("GetAllCategories()"))
    {
        if (context.Cache["StoreCategories"] == null)
        {
            var r = new List<Category>();
            using (var db = new MainContext())
            {
                var q = db.v2StoreCategories;
                foreach (var cat in q)
                {
                    r.Add(new Category(cat));
                }
            }
            context.Cache["StoreCategories"] = r;
        }
    }
    return (List<Category>)HttpContext.Current.Cache["StoreCategories"];
}

假设我需要建立一种每隔n分钟刷新一次缓存的方法,那么最好的方法是什么?

在global.asax中有一个定时事件可以安全吗?

2 个答案:

答案 0 :(得分:0)

使用类似

的内容
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));

适用的地方。

确保使用正确的上下文。即

HttpContext.Current

答案 1 :(得分:0)

我建议您使用Cache.Insert(...)方法。这样,您可以为缓存中的对象提供生存时间。像这样:

public static List<Category> GetAllCategories()
{
    var context = HttpContext.Current;
    var profiler = MiniProfiler.Current;
    using (profiler.Step("GetAllCategories()"))
    {
        if (context.Cache["StoreCategories"] == null)
        {
            var r = new List<Category>();
            using (var db = new MainContext())
            {
                var q = db.v2StoreCategories;
                foreach (var cat in q)
                {
                    r.Add(new Category(cat));
                }
            }
            HttpContext.Current.Cache.Insert(
                "StoreCategories",
                r,
                null,
                DateTime.UtcNow.AddMinutes(1),  // TTL = one minute in this sample
                TimeSpan.Zero
            );
        }
    }
    return (List<Category>)HttpContext.Current.Cache["StoreCategories"];
}

然后缓存框架会在它变老时自动从缓存中删除该对象,然后您的方法将在下次调用时重新创建它。

您还可以在Cache.Insert中提供一个回调方法,该方法将在缓存对象到期时自动调用。然后,回调可以在后台工作以刷新缓存的对象。这样,用户就不必等待构建缓存对象了:

HttpContext.Current.Cache.Insert(
    "StoreCategories",
    r,
    null,
    DateTime.UtcNow.AddMinutes(1),
    TimeSpan.Zero,
    UpdateCategoriesCache
);

private static void UpdateCategoriesCache(
    string key,
    System.Web.Caching.CacheItemUpdateReason reason,
    out Object categories,
    out CacheDependency dependency,
    out DateTime absoluteExpiration,
    out TimeSpan slidingExpiration
)
{
    // fetch categories here
    categories = fetchedCategories;
    dependency = null;
    absoluteExpiration = DateTime.UtcNow.AddMinutes(1);
    slidingExpiration = TimeSpan.Zero;
}