gpt4 book ai didi

c# - 是什么导致我的 httpcontext.cache 在我的 C# MVC Web 应用程序中被删除?

转载 作者:太空宇宙 更新时间:2023-11-03 23:29:46 24 4
gpt4 key购买 nike

我们有一个网络应用程序可以从 SOAP 网络服务中检索大量数据,并且需要大约 4 到 5 分钟才能完成。为了确保用户不会被此打扰,数据会像这样缓存:

//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());
}

我有来自 www.site24x7.com 的服务每小时创建一次缓存,因此理论上它应该在凌晨 0:00 之后创建一个缓存并创建另一个缓存。但出于某种原因,缓存被删除,网站每天多次创建一个新缓存,这也让用户感到困扰,加载时间极长。

这是我的 Nlog 日志的一部分:

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

编辑

我实现了NightOwl888给出的答案,但是没有用,缓存一直被移除。

这是我当前的 Nlog 文件的一部分:

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

您可以看到,Site24x7 有时会连续多次调用 GetSummariesAsync 函数。

而且用户也(尽管很少)遇到问题。

从创建现金到移除现金之间的时间可以短至 8 分钟。

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

最佳答案

我不知道这是否是您问题的根源,但我看到您遇到了由多个线程调用您的 GetAllSummaries 方法引起的竞争条件。

当多个线程正在填充缓存时,您可能会收到错误的日志条目(由于冲突导致多余的条目被删除)并且用户遇到问题只是因为多个线程在填充缓存之前竞争系统资源.

首先,看一下Cache.Add的文档方法:

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.

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.

(强调)

此外,您的缓存检查代码不是线程安全的。多个线程可以运行 GetAllSummaries 方法,因为缓存在第一次调用返回之前不会有值。由于 Add 方法不会因为重复而抛出异常,所以这些努力就白费了。

您可以通过以下方式解决此问题:

  1. 创建一个对象来包装缓存,以便对缓存进行线程安全的多次调用。
  2. 使用 double-checked locking pattern以确保只允许一个线程通过以获取数据。
  3. 使用缓存包装器的静态实例,确保所有线程使用相同的线程锁定代码。

摘要缓存

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

用法

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

关于c# - 是什么导致我的 httpcontext.cache 在我的 C# MVC Web 应用程序中被删除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32725206/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com