是什么原因造成我httpcontext.cache在我的C#MVC的Web应用程序被删除? [英] What is causing my httpcontext.cache to be removed in my c# MVC web application?

查看:113
本文介绍了是什么原因造成我httpcontext.cache在我的C#MVC的Web应用程序被删除?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有从SOAP Web服务检索大量数据,大约需要4到5分钟,这样做的一个Web应用程序。
为了确保用户不会受此困扰,数据缓存,像这样:

  //使用NLOG登录缓存行为
私人记录器记录= LogManager.GetCurrentClassLogger();
//公众的ActionResult得到摘要用Ajax调用或site24x7服务
公众的ActionResult GetSummariesAsync()
{
  log.Info(的String.Format(GetSummariesAsync称为));
  清单< ProjectDataSummary>摘要= GetAllSummaries();
  log.Info(的String.Format({0}发现摘要,summaries.Count));
  清单< ProjectDataSummary>缓存= HttpContext.Cache [SummariesCache]作为名单< ProjectDataSummary取代;
  log.Info(的String.Format({0}高速缓存,cache.Count));  返回JSON(摘要,JsonRequestBehavior.AllowGet);
}
私人列表< ProjectDataSummary> GetAllSummaries()
{
  清单< ProjectDataSummary>摘要=新的List< ProjectDataSummary>();
  //使用在web.config中设定,如果我们要强制不缓存,但在发布的版本设置为false
  如果(ConfigurationManager.AppSettings [非缓存] ==真)
  {
    摘要= _service.GetAllSummaries();
  }
  其他
  {
    //从缓存中获取摘要(如果可用)
    摘要= HttpContext.Cache [SummariesCache]作为名单< ProjectDataSummary取代;
    如果(摘要== NULL)
    {
      //缓存空,检索值
      摘要= _service.GetAllSummaries();
      //它缓存
      HttpContext.Cache.Add(SummariesCache,摘要,空,新的日期时间(DateTime.Now.Year,DateTime.Now.Month,DateTime.Now.Day,23,59,59),Cache.NoSlidingExpiration,CacheItemPriority.NotRemovable,新CacheItemRemovedCallback(this.cacheCallback));
    }
  }
  返回摘要;
}
私人无效cacheCallback(字符串K,宾语,CacheItemRemovedReason R)
{
  CacheItemRemovedReason原因= R;
  log.Info(缓存过期,原因是:{0},r.ToString());
}

我从 www.site24x7.com服务命中缓存的创建每隔一小时,以便在理论上应该打有点过去的0:00,并使其创建另一个缓存。但由于某些原因缓存被删除,该网站每天创建一个新的几次,也困扰着用户具有极长的加载时间。

下面是从我NLOG日志的一部分:

  2015年9月22日18:31:07.8746 GetSummariesAsync信息GetSummariesAsync称为
2015年9月22日18:31:07.8901 GetSummariesAsync信息263摘要
2015年9月22日18:31:07.8901 GetSummariesAsync信息263缓存
2015年9月22日18:52:15.9684 cacheCallback信息缓存过期,原因:删除
2015年9月22日19:02:06.9839 cacheCallback信息缓存过期,原因:删除
2015年9月22日19:23:08.3590 cacheCallback信息缓存过期,原因:删除
2015年9月22日19:31:42.7182 GetSummariesAsync信息GetSummariesAsync称为
2015年9月22日19:32:15.0776 GetSummariesAsync信息GetSummariesAsync称为
2015年9月22日19:32:46.2495 GetSummariesAsync信息GetSummariesAsync称为
2015年9月22日19:33:01.8276 GetSummariesAsync信息GetSummariesAsync称为
2015年9月22日19:33:18.3746 GetSummariesAsync信息GetSummariesAsync称为
2015年9月22日19:33:34.8589 GetSummariesAsync信息GetSummariesAsync称为
2015年9月22日19:34:10.7182 GetSummariesAsync信息GetSummariesAsync称为
2015年9月22日19:34:15.4215 GetSummariesAsync信息263摘要
2015年9月22日19:34:15.4215 GetSummariesAsync信息263缓存
2015年9月22日19:35:07.3121 GetSummariesAsync信息263的摘要
2015年9月22日19:35:07.3121 GetSummariesAsync信息263中的高速缓存
2015年9月22日19:36:07.9213 GetSummariesAsync信息263摘要
2015年9月22日19:36:07.9213 GetSummariesAsync信息263中的高速缓存
2015年9月22日19:36:19.5309 GetSummariesAsync信息263摘要
2015年9月22日19:36:19.5309 GetSummariesAsync信息263中的高速缓存
2015年9月22日19:36:36.3588 GetSummariesAsync信息263摘要
2015年9月22日19:36:36.3588 GetSummariesAsync信息263中的高速缓存
2015年9月22日19:37:07.9996 GetSummariesAsync信息263的摘要
2015年9月22日19:37:07.9996 GetSummariesAsync信息263中的高速缓存
2015年9月22日19:37:33.7183 GetSummariesAsync信息263的摘要
2015年9月22日19:37:33.7183 GetSummariesAsync信息263中的高速缓存
2015年9月22日19:37:59.8747 GetSummariesAsync信息GetSummariesAsync称为
2015年9月22日19:37:59.8747 GetSummariesAsync信息263的摘要
2015年9月22日19:37:59.8747 GetSummariesAsync信息263中的高速缓存
2015年9月22日19:44:00.2496 cacheCallback信息缓存过期,原因:删除
2015年9月22日19:54:25.2183 cacheCallback信息缓存过期,原因:删除
2015年9月22日20:34:55.3589 GetSummariesAsync信息GetSummariesAsync称为
2015年9月22日20:34:55.3745 GetSummariesAsync信息263摘要
2015年9月22日20:34:55.3745 GetSummariesAsync信息263缓存
2015年9月22日20:44:32.5153 cacheCallback信息缓存过期,原因:删除
2015年9月22日20:56:38.8746 cacheCallback信息缓存过期,原因:删除


修改

我已经实现了答案NightOwl888给了,但无济于事,缓存不断被删除。

下面是我目前NLOG文件部分:

  2015年9月27日20:05:发现29.9682 Controllers.HomeController.GetSummariesAsync信息263摘要
2015年9月27日20:05:29.9682 Controllers.HomeController.GetSummariesAsync信息263缓存中找到
2015年9月27日20:23:51.5464 Controllers.HomeController.cacheCallback信息缓存过期,原因:删除
2015年9月27日20:23:51.5464 Controllers.HomeController.cacheCallback信息缓存过期,原因:删除
2015年9月27日20:23:51.5464 Controllers.HomeController.cacheCallback信息缓存过期,原因:删除
2015年9月27日20:25:创建48.1714 Models.CachingBase`1.GetItemsCache信息缓存fileEntries
2015年9月27日20:25:48.1714 Models.CachingBase`1.GetItemsCache信息缓存idCertificaat创建
2015年9月27日20:26:46.3588 Controllers.HomeController.Index信息没有找到缓存,家庭/索引需要创造现金异步
2015年9月27日20:26:46.7963 Controllers.HomeController.GetSummariesAsync信息GetSummariesAsync通过用户代理触发:Mozilla的/ 5.0(Windows NT的6.3; WOW64; RV:40.0)的Gecko / 20100101火狐/ 40.0 vanuit主持人:88.159.95.251
2015年9月27日20:27:26.9682 Models.CachingBase`1.GetItemsCache信息缓存GebouwProjectenSummaries创建
发现26.9682 Controllers.HomeController.GetSummariesAsync信息263摘要:2015年9月27日20:27
2015年9月27日20:27:26.9682 Controllers.HomeController.GetSummariesAsync信息263缓存中找到
2015年9月27日20:33:48.7340 Controllers.HomeController.cacheCallback信息缓存过期,原因:删除
2015年9月27日20:33:48.7340 Controllers.HomeController.cacheCallback信息缓存过期,原因:删除
2015年9月27日20:33:48.7340 Controllers.HomeController.cacheCallback信息缓存过期,原因:删除
2015年9月27日20:38:创建21.0151 Models.CachingBase`1.GetItemsCache信息缓存fileEntries
2015年9月27日20:38:21.0151 Models.CachingBase`1.GetItemsCache信息缓存idCertificaat创建
2015年9月27日20:38:21.0620 Controllers.HomeController.Index信息没有找到缓存,家庭/索引需要创造现金异步
2015年9月27日20:43:41.0620 Controllers.HomeController.Index信息没有找到缓存,家庭/索引需要创造现金异步
2015年9月27日20:46:29.0620 Models.CachingBase`1.GetItemsCache信息缓存GebouwProjectenSummaries创建
2015年9月27日20:57:21.5776 Controllers.HomeController.cacheCallback信息缓存过期,原因:删除
2015年9月27日20:57:21.5776 Controllers.HomeController.cacheCallback信息缓存过期,原因:删除
2015年9月27日20:57:21.5776 Controllers.HomeController.cacheCallback信息缓存过期,原因:删除
2015年9月27日20:58:创建23.9553 Models.CachingBase`1.GetItemsCache信息缓存fileEntries
2015年9月27日20:58:23.9553 Models.CachingBase`1.GetItemsCache信息缓存idCertificaat创建
2015年9月27日20:58:23.9839 Controllers.HomeController.Index信息没有找到缓存,家庭/索引需要创造现金异步
2015年9月27日21:04:24.5151 Controllers.HomeController.cacheCallback信息缓存过期,原因:删除
2015年9月27日21:04:24.5151 Controllers.HomeController.cacheCallback信息缓存过期,原因:删除
2015年9月27日21:05:创建31.8277 Models.CachingBase`1.GetItemsCache信息缓存fileEntries
2015年9月27日21:05:31.8277 Models.CachingBase`1.GetItemsCache信息缓存idCertificaat创建
2015年9月27日21:05:31.8432 Controllers.HomeController.GetSummariesAsync信息GetSummariesAsync触发了的User-Agent:Site24x7 vanuit主持人:72.5.230.111
2015年9月27日21:06:03.5307 Controllers.HomeController.GetSummariesAsync信息GetSummariesAsync触发了的User-Agent:Site24x7 vanuit主持人:72.5.230.111
2015年9月27日21:06:36.3433 Controllers.HomeController.GetSummariesAsync信息GetSummariesAsync触发了的User-Agent:Site24x7 vanuit主持人:120.138.27.125
2015年9月27日21:06:40.2651 Controllers.HomeController.GetSummariesAsync信息GetSummariesAsync触发了的User-Agent:Site24x7 vanuit主持人:119.81.237.98
2015年9月27日21:07:08.6401 Controllers.HomeController.GetSummariesAsync信息GetSummariesAsync触发了的User-Agent:Site24x7 vanuit主持人:120.138.27.125
2015年9月27日21:07:11.4057 Models.CachingBase`1.GetItemsCache信息缓存GebouwProjectenSummaries创建
发现11.4057 Controllers.HomeController.GetSummariesAsync信息263摘要:2015年9月27日21:07
发现11.4057 Controllers.HomeController.GetSummariesAsync信息263摘要:2015年9月27日21:07
2015年9月27日21:07:11.4057 Controllers.HomeController.GetSummariesAsync信息263缓存中找到
2015年9月27日21:07:11.4057 Controllers.HomeController.GetSummariesAsync信息263缓存中找到
发现11.4214 Controllers.HomeController.GetSummariesAsync信息263摘要:2015年9月27日21:07
2015年9月27日21:07:11.4214 Controllers.HomeController.GetSummariesAsync信息263缓存中找到
发现11.4214 Controllers.HomeController.GetSummariesAsync信息263摘要:2015年9月27日21:07
2015年9月27日21:07:11.4214 Controllers.HomeController.GetSummariesAsync信息263缓存中找到
发现11.4214 Controllers.HomeController.GetSummariesAsync信息263摘要:2015年9月27日21:07
2015年9月27日21:07:11.4214 Controllers.HomeController.GetSummariesAsync信息263缓存中找到
2015年9月27日21:07:12.5620 Controllers.HomeController.GetSummariesAsync信息GetSummariesAsync触发了的User-Agent:Site24x7 vanuit主持人:119.81.237.98
发现12.5620 Controllers.HomeController.GetSummariesAsync信息263摘要:2015年9月27日21:07
2015年9月27日21:07:12.5620 Controllers.HomeController.GetSummariesAsync信息263缓存中找到
2015年9月27日21:15:32.4370 Controllers.HomeController.cacheCallback信息缓存过期,原因:删除
2015年9月27日21:15:32.4370 Controllers.HomeController.cacheCallback信息缓存过期,原因:删除
2015年9月27日21:15:32.4370 Controllers.HomeController.cacheCallback信息缓存过期,原因:删除

你能看到的是,Site24x7多次有时调用GetSummariesAsync功能在一排。

和用户也(虽然很少次)出现问题。

创建现金及其除去的之间的时间可以是短至8分钟。

我现在已经停用了site24x7检查,看看是否是罪魁祸首。


解决方案

我不知道这是不是你的问题的根源,但我看到你有引起多个线程调用你的<$ C $的竞争条件C> GetAllSummaries 方法。

这有可能是你得到虚假的日志条目当多个线程填充缓存(所造成的多余项,因为冲突被删除),用户仅经历,因为多个线程的问题,为竞争系统资源之前缓存填充

首先,来看看的的 Cache.Add 方式:


  

调用此方法,如果具有相同的键参数的项目已存储在高速缓存将失败。要使用相同的密钥参数覆盖现有的缓存项,请使用的插入方法。


更重要的是


  

如果您使用Add方法,并使用相同的名称已经存在于缓存中的项目,该方法不会更换的项目和将不会产生异常


(强调)

此外,缓存检查code不是线程安全的。多个线程可以运行 GetAllSummaries 方法,因为缓存不会有一个值,直到第一次调用返回。而且,由于添加方法不抛出,因为重复的一个例外,那努力只是浪费。

您可以修复方式:


  1. 使对象包装与制作,你必须缓存线程安全的多个调用缓存中。

  2. 使用双重检查锁定模式,以确保只有一个线程是通过让获取数据。

  3. 使用高速缓存包装,以确保所有线程使用同一个线程锁code的静态实例。

SummariesCache

 公共密封类SummariesCache
{
    私人ReaderWriterLockSlim的SyncLock =
        新的ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);    公开名单&LT; ProjectSummaryData&GT; GetSummaries(
        ISummariesService服务,
        REF CacheItemRemovedCallback onRemoveCallback)
    {
        清单&LT; ProjectDataSummary&GT;摘要;
        字符串键=SummariesCache;
        布尔成功;        synclock.EnterReadLock();
        尝试
        {
            成功= TryGetCacheValue(键,总结出);
        }
        最后
        {
            synclock.ExitReadLock();
        }        如果(!成功)
        {
            synclock.EnterWriteLock();
            尝试
            {
                如果(!TryGetCacheValue(键,总结出))
                {
                    //缓存空,检索值
                    摘要= service.GetAllSummaries();                    //加载缓存(使用插入)
                    HttpContext.Current.Cache.Insert(
                        键,
                        摘要,
                        空值,
                        新的日期时间(DateTime.Now.Year,DateTime.Now.Month,DateTime.Now.Day,23,59,59)
                        Cache.NoSlidingExpiration,
                        CacheItemPriority.NotRemovable,
                        onRemoveCallback
                    );
                }
            }
            最后
            {
                synclock.ExitWriteLock();
            }
        }        返回摘要;
    }    私人布尔TryGetCacheValue(字符串键,淘汰名单,LT; ProjectSummaryData&GT;值)
    {
        值= HttpContext.Current.Cache [钥匙]作为名单&LT; ProjectDataSummary取代;
        如果(值!= NULL)
        {
            返回true;
        }
        返回false;
    }
}

用法

  //使用缓存的静态实例,以确保所有线程使用它。
私有静态_summariesCache =新SummariesCache();私人列表&LT; ProjectDataSummary&GT; GetAllSummaries()
{
    清单&LT; ProjectDataSummary&GT;摘要=新的List&LT; ProjectDataSummary&GT;();
    //使用在web.config中设定,如果我们要强制不缓存,但在发布的版本设置为false
    如果(ConfigurationManager.AppSettings [非缓存] ==真)
    {
        摘要= _service.GetAllSummaries();
    }
    其他
    {
        摘要= _summariesCache.GetSummaries(_service,新CacheItemRemovedCallback(cacheCallback));
    }
    返回摘要;
}私人无效cacheCallback(字符串K,宾语,CacheItemRemovedReason R)
{
    CacheItemRemovedReason原因= R;
    log.Info(缓存过期,原因是:{0},r.ToString());
}


  

注意://www.superstar$c$crs.com/blogs/posts/micro-caching-in:其中大部分code的是从的微缓存在.NET中。如果preFER,你可以使用该解决方案。


We have a web application that retrieves a lot of data from a SOAP webservice and takes about 4 to 5 minutes to do so. To make sure users are not bothered by this, the data is cached like so:

//using Nlog to log caching behaviour
private Logger log = LogManager.GetCurrentClassLogger();
//a public actionresult to get the summaries with an ajax call or site24x7 service
public ActionResult GetSummariesAsync()
{
  log.Info(String.Format("GetSummariesAsync called"));
  List<ProjectDataSummary> summaries = GetAllSummaries();
  log.Info(String.Format("{0} summaries found", summaries.Count));
  List<ProjectDataSummary> cache = HttpContext.Cache["SummariesCache"] as List<ProjectDataSummary>;
  log.Info(String.Format("{0} in cache", cache.Count));

  return Json(summaries, JsonRequestBehavior.AllowGet);
}
private List<ProjectDataSummary> GetAllSummaries()
{
  List<ProjectDataSummary> summaries = new List<ProjectDataSummary>();
  //use setting in web.config if we want to force no cache, but set to false in released version
  if (ConfigurationManager.AppSettings["NoCache"] == "true")
  {
    summaries = _service.GetAllSummaries();
  }
  else
  {
    //get summaries from cache if available
    summaries = HttpContext.Cache["SummariesCache"] as List<ProjectDataSummary>;
    if (summaries == null)
    {
      //cache empty, retrieve values
      summaries = _service.GetAllSummaries();
      //cache it
      HttpContext.Cache.Add("SummariesCache", summaries, null, new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 23, 59, 59), Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, new CacheItemRemovedCallback(this.cacheCallback));
    }
  }
  return summaries;
}
private void cacheCallback(String K, Object v, CacheItemRemovedReason r)
{
  CacheItemRemovedReason reason = r;
  log.Info("Cache expired, reason: {0}", r.ToString());
}

I have a service from www.site24x7.com hit the cache creation every hour so in theory it should hit it a bit past 0:00 am and make it create another cache. But for some reason the cache gets removed and the site creates a new one several times a day, also bothering users with extremely long loading times.

Here is a part from my Nlog log:

2015-09-22 18:31:07.8746 GetSummariesAsync Info GetSummariesAsync called 
2015-09-22 18:31:07.8901 GetSummariesAsync Info 263 summaries 
2015-09-22 18:31:07.8901 GetSummariesAsync Info 263 in cache 
2015-09-22 18:52:15.9684 cacheCallback Info Cache expired, reason: Removed 
2015-09-22 19:02:06.9839 cacheCallback Info Cache expired, reason: Removed 
2015-09-22 19:23:08.3590 cacheCallback Info Cache expired, reason: Removed 
2015-09-22 19:31:42.7182 GetSummariesAsync Info GetSummariesAsync called 
2015-09-22 19:32:15.0776 GetSummariesAsync Info GetSummariesAsync called 
2015-09-22 19:32:46.2495 GetSummariesAsync Info GetSummariesAsync called 
2015-09-22 19:33:01.8276 GetSummariesAsync Info GetSummariesAsync called 
2015-09-22 19:33:18.3746 GetSummariesAsync Info GetSummariesAsync called 
2015-09-22 19:33:34.8589 GetSummariesAsync Info GetSummariesAsync called 
2015-09-22 19:34:10.7182 GetSummariesAsync Info GetSummariesAsync called 
2015-09-22 19:34:15.4215 GetSummariesAsync Info 263 summaries 
2015-09-22 19:34:15.4215 GetSummariesAsync Info 263 in cache 
2015-09-22 19:35:07.3121 GetSummariesAsync Info 263 summaries 
2015-09-22 19:35:07.3121 GetSummariesAsync Info 263 in cache 
2015-09-22 19:36:07.9213 GetSummariesAsync Info 263 summaries 
2015-09-22 19:36:07.9213 GetSummariesAsync Info 263 in cache 
2015-09-22 19:36:19.5309 GetSummariesAsync Info 263 summaries 
2015-09-22 19:36:19.5309 GetSummariesAsync Info 263 in cache 
2015-09-22 19:36:36.3588 GetSummariesAsync Info 263 summaries 
2015-09-22 19:36:36.3588 GetSummariesAsync Info 263 in cache 
2015-09-22 19:37:07.9996 GetSummariesAsync Info 263 summaries 
2015-09-22 19:37:07.9996 GetSummariesAsync Info 263 in cache 
2015-09-22 19:37:33.7183 GetSummariesAsync Info 263 summaries 
2015-09-22 19:37:33.7183 GetSummariesAsync Info 263 in cache 
2015-09-22 19:37:59.8747 GetSummariesAsync Info GetSummariesAsync called 
2015-09-22 19:37:59.8747 GetSummariesAsync Info 263 summaries 
2015-09-22 19:37:59.8747 GetSummariesAsync Info 263 in cache 
2015-09-22 19:44:00.2496 cacheCallback Info Cache expired, reason: Removed 
2015-09-22 19:54:25.2183 cacheCallback Info Cache expired, reason: Removed 
2015-09-22 20:34:55.3589 GetSummariesAsync Info GetSummariesAsync called 
2015-09-22 20:34:55.3745 GetSummariesAsync Info 263 summaries 
2015-09-22 20:34:55.3745 GetSummariesAsync Info 263 in cache 
2015-09-22 20:44:32.5153 cacheCallback Info Cache expired, reason: Removed 
2015-09-22 20:56:38.8746 cacheCallback Info Cache expired, reason: Removed


Edit

I have Implemented the answer NightOwl888 has given, but to no avail, the cache keeps being removed.

Here is a section from my current Nlog file:

2015-09-27 20:05:29.9682 Controllers.HomeController.GetSummariesAsync Info 263 summaries found 
2015-09-27 20:05:29.9682 Controllers.HomeController.GetSummariesAsync Info 263 in cache found 
2015-09-27 20:23:51.5464 Controllers.HomeController.cacheCallback Info Cache expired, reason: Removed 
2015-09-27 20:23:51.5464 Controllers.HomeController.cacheCallback Info Cache expired, reason: Removed 
2015-09-27 20:23:51.5464 Controllers.HomeController.cacheCallback Info Cache expired, reason: Removed 
2015-09-27 20:25:48.1714 Models.CachingBase`1.GetItemsCache Info Cache fileEntries created 
2015-09-27 20:25:48.1714 Models.CachingBase`1.GetItemsCache Info Cache idCertificaat created 
2015-09-27 20:26:46.3588 Controllers.HomeController.Index Info No cache found, Home/Index needs to create the cash Async 
2015-09-27 20:26:46.7963 Controllers.HomeController.GetSummariesAsync Info GetSummariesAsync triggered by User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0 vanuit Host: 88.159.95.251 
2015-09-27 20:27:26.9682 Models.CachingBase`1.GetItemsCache Info Cache GebouwProjectenSummaries created 
2015-09-27 20:27:26.9682 Controllers.HomeController.GetSummariesAsync Info 263 summaries found 
2015-09-27 20:27:26.9682 Controllers.HomeController.GetSummariesAsync Info 263 in cache found 
2015-09-27 20:33:48.7340 Controllers.HomeController.cacheCallback Info Cache expired, reason: Removed 
2015-09-27 20:33:48.7340 Controllers.HomeController.cacheCallback Info Cache expired, reason: Removed 
2015-09-27 20:33:48.7340 Controllers.HomeController.cacheCallback Info Cache expired, reason: Removed 
2015-09-27 20:38:21.0151 Models.CachingBase`1.GetItemsCache Info Cache fileEntries created 
2015-09-27 20:38:21.0151 Models.CachingBase`1.GetItemsCache Info Cache idCertificaat created 
2015-09-27 20:38:21.0620 Controllers.HomeController.Index Info No cache found, Home/Index needs to create the cash Async 
2015-09-27 20:43:41.0620 Controllers.HomeController.Index Info No cache found, Home/Index needs to create the cash Async 
2015-09-27 20:46:29.0620 Models.CachingBase`1.GetItemsCache Info Cache GebouwProjectenSummaries created 
2015-09-27 20:57:21.5776 Controllers.HomeController.cacheCallback Info Cache expired, reason: Removed 
2015-09-27 20:57:21.5776 Controllers.HomeController.cacheCallback Info Cache expired, reason: Removed 
2015-09-27 20:57:21.5776 Controllers.HomeController.cacheCallback Info Cache expired, reason: Removed 
2015-09-27 20:58:23.9553 Models.CachingBase`1.GetItemsCache Info Cache fileEntries created 
2015-09-27 20:58:23.9553 Models.CachingBase`1.GetItemsCache Info Cache idCertificaat created 
2015-09-27 20:58:23.9839 Controllers.HomeController.Index Info No cache found, Home/Index needs to create the cash Async 
2015-09-27 21:04:24.5151 Controllers.HomeController.cacheCallback Info Cache expired, reason: Removed 
2015-09-27 21:04:24.5151 Controllers.HomeController.cacheCallback Info Cache expired, reason: Removed 
2015-09-27 21:05:31.8277 Models.CachingBase`1.GetItemsCache Info Cache fileEntries created 
2015-09-27 21:05:31.8277 Models.CachingBase`1.GetItemsCache Info Cache idCertificaat created 
2015-09-27 21:05:31.8432 Controllers.HomeController.GetSummariesAsync Info GetSummariesAsync triggered by User-Agent: Site24x7 vanuit Host: 72.5.230.111 
2015-09-27 21:06:03.5307 Controllers.HomeController.GetSummariesAsync Info GetSummariesAsync triggered by User-Agent: Site24x7 vanuit Host: 72.5.230.111 
2015-09-27 21:06:36.3433 Controllers.HomeController.GetSummariesAsync Info GetSummariesAsync triggered by User-Agent: Site24x7 vanuit Host: 120.138.27.125 
2015-09-27 21:06:40.2651 Controllers.HomeController.GetSummariesAsync Info GetSummariesAsync triggered by User-Agent: Site24x7 vanuit Host: 119.81.237.98 
2015-09-27 21:07:08.6401 Controllers.HomeController.GetSummariesAsync Info GetSummariesAsync triggered by User-Agent: Site24x7 vanuit Host: 120.138.27.125 
2015-09-27 21:07:11.4057 Models.CachingBase`1.GetItemsCache Info Cache GebouwProjectenSummaries created 
2015-09-27 21:07:11.4057 Controllers.HomeController.GetSummariesAsync Info 263 summaries found 
2015-09-27 21:07:11.4057 Controllers.HomeController.GetSummariesAsync Info 263 summaries found 
2015-09-27 21:07:11.4057 Controllers.HomeController.GetSummariesAsync Info 263 in cache found 
2015-09-27 21:07:11.4057 Controllers.HomeController.GetSummariesAsync Info 263 in cache found 
2015-09-27 21:07:11.4214 Controllers.HomeController.GetSummariesAsync Info 263 summaries found 
2015-09-27 21:07:11.4214 Controllers.HomeController.GetSummariesAsync Info 263 in cache found 
2015-09-27 21:07:11.4214 Controllers.HomeController.GetSummariesAsync Info 263 summaries found 
2015-09-27 21:07:11.4214 Controllers.HomeController.GetSummariesAsync Info 263 in cache found 
2015-09-27 21:07:11.4214 Controllers.HomeController.GetSummariesAsync Info 263 summaries found 
2015-09-27 21:07:11.4214 Controllers.HomeController.GetSummariesAsync Info 263 in cache found 
2015-09-27 21:07:12.5620 Controllers.HomeController.GetSummariesAsync Info GetSummariesAsync triggered by User-Agent: Site24x7 vanuit Host: 119.81.237.98 
2015-09-27 21:07:12.5620 Controllers.HomeController.GetSummariesAsync Info 263 summaries found 
2015-09-27 21:07:12.5620 Controllers.HomeController.GetSummariesAsync Info 263 in cache found 
2015-09-27 21:15:32.4370 Controllers.HomeController.cacheCallback Info Cache expired, reason: Removed 
2015-09-27 21:15:32.4370 Controllers.HomeController.cacheCallback Info Cache expired, reason: Removed 
2015-09-27 21:15:32.4370 Controllers.HomeController.cacheCallback Info Cache expired, reason: Removed 

What you can see is that Site24x7 sometimes calls the GetSummariesAsync function multiple times in a row.

And that users also (although very few times) experience problems.

The time between the creation of the cash and its removal can be as short as 8 minutes.

I have now disabled my site24x7 checks to see if that is the culprit.

解决方案

I don't know if this is the root of your problem, but I see that you have a race condition caused by multiple threads calling your GetAllSummaries method.

It's possible that you are getting false log entries when multiple threads are populating the cache (caused by the excess entries being removed because of collisions) and users are only experiencing problems because of multiple threads competing for system resources before the cache is populated.

First of all, take a look at the documentation of the Cache.Add method:

Calls to this method will fail if an item with the same key parameter is already stored in the Cache. To overwrite an existing Cache item using the same key parameter, use the Insert method.

And more importantly:

if you use the Add method and an item with the same name already exists in the cache, the method will not replace the item and will not raise an exception.

(emphasis added)

In addition, your cache checking code is not thread-safe. More than one thread can run the GetAllSummaries method because the cache will not have a value until the first call to it returns. And since the Add method doesn't throw an exception because of the duplicate, that effort is just wasted.

You can fix that by:

  1. Making an object to wrap the cache with to make the multiple calls that you have to the cache thread-safe.
  2. Using a double-checked locking pattern to ensure only one thread is let through to get the data.
  3. Using a static instance of the cache wrapper, which ensures all threads use the same thread-locking code.

SummariesCache

public sealed class SummariesCache
{
    private ReaderWriterLockSlim synclock = 
        new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);

    public List<ProjectSummaryData> GetSummaries(
        ISummariesService service, 
        ref CacheItemRemovedCallback onRemoveCallback)
    {
        List<ProjectDataSummary> summaries;
        string key = "SummariesCache";
        bool success;

        synclock.EnterReadLock();
        try
        {
            success = TryGetCacheValue(key, out summaries);
        }
        finally
        {
            synclock.ExitReadLock();
        }

        if (!success)
        {
            synclock.EnterWriteLock();
            try
            {
                if (!TryGetCacheValue(key, out summaries))
                {
                    //cache empty, retrieve values
                    summaries = service.GetAllSummaries();

                    // load the cache (using Insert)
                    HttpContext.Current.Cache.Insert(
                        key, 
                        summaries, 
                        null, 
                        new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 23, 59, 59), 
                        Cache.NoSlidingExpiration, 
                        CacheItemPriority.NotRemovable, 
                        onRemoveCallback
                    );
                }
            }
            finally
            {
                synclock.ExitWriteLock();
            }
        }

        return summaries;
    }

    private bool TryGetCacheValue(string key, out List<ProjectSummaryData> value)
    {
        value = HttpContext.Current.Cache["key"] as List<ProjectDataSummary>;
        if (value != null)
        {
            return true;
        }
        return false;
    }
}

Usage

// Use a static instance of the cache to ensure all threads use it.
private static _summariesCache = new SummariesCache();

private List<ProjectDataSummary> GetAllSummaries()
{
    List<ProjectDataSummary> summaries = new List<ProjectDataSummary>();
    //use setting in web.config if we want to force no cache, but set to false in released version
    if (ConfigurationManager.AppSettings["NoCache"] == "true")
    {
        summaries = _service.GetAllSummaries();
    }
    else
    {
        summaries = _summariesCache.GetSummaries(_service, new CacheItemRemovedCallback(cacheCallback));
    }
    return summaries;
}

private void cacheCallback(String K, Object v, CacheItemRemovedReason r)
{
    CacheItemRemovedReason reason = r;
    log.Info("Cache expired, reason: {0}", r.ToString());
}

NOTE: Most of this code was borrowed from Micro-Caching in .NET. If you prefer, you can just use that solution.

这篇关于是什么原因造成我httpcontext.cache在我的C#MVC的Web应用程序被删除?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆