在asp.net httpContext.Cache中存储/检索项目的最有效方法是什么

leo*_*ora 17 asp.net asp.net-mvc caching httpcontext.cache

我有一个网站,我在那里缓存了很多信息.我看到有关在asp.net缓存中存储东西的相互矛盾的信息.

例如,假设我有这样的数据结构:

 Dictionary<string, List<Car>> mydictionary;
Run Code Online (Sandbox Code Playgroud)

我可以使用字符串键将整个事物存储为"MyDictionary",然后在我拉出对象时向下钻取.

 HttpContext.Cache.Add("MyDictionary",  
   mydictionary, 
   null, 
   Cache.NoAbsoluteExpiration,
   new TimeSpan(10, 0, 0),
   CacheItemPriority.Normal,
   null);

 var myDict = HttpContext.Cache["MyDictionary"] as Dictionary<string, List<Car>>;
Run Code Online (Sandbox Code Playgroud)

我能做的另一件事是将其分解并将我的字典中的每个项目分别存储在缓存中(无论如何缓存都是字典).

 Dictionary<string, List<Car>> mydictionary;

 foreach (var item in mydictionary.Keys)
 {
      HttpContext.Cache.Add(item, mydictionary[item], null, Cache.NoAbsoluteExpiration, new TimeSpan(10, 0, 0), CacheItemPriority.Normal, null);
 }

 var myitem = "test";
 var myDict = HttpContext.Cache[myItem] as List<Car>;
Run Code Online (Sandbox Code Playgroud)

性能含义是否会非常不同(假设我假设一切都在内存中?)

Dav*_*bbo 14

在这里添加一个额外的答案,因为我觉得现有的答案捕获'什么'但不足以'为什么'.

最好将各个条目分别存储在缓存中的原因与perf几乎没有关系.相反,它与允许系统执行适当的内存管理有关.

ASP.NET缓存中有很多逻辑可以确定在遇到内存压力时要做什么.最后,它需要踢出一些项目,它需要以最少的破坏性方式做到这一点.它选择推出哪些项目取决于他们最近是否被访问过.还有其他因素,例如在缓存时传递的标志.例如,你可以使一个项目不可移动,它永远不会被踢出去.

但回到这个问题,如果你将整个字典存储为单个项目,那么你只需要为ASP.NET内存管理器留下两个选项:保持整个事物的存活,或者杀死整个事物.也就是说,你完全失去了让你的"热门"物品留在缓存中的好处,而你很少被访问的内存占用物品被淘汰出局.换句话说,您将失去任何级别的缓存粒度.

当然,您可以选择在字典中实现自己的方案,以删除很少使用的项目.但是那时你正在重新发明轮子,而你的新轮子将无法正常工作,因为它不会与系统的其他部分协调.


Eri*_*sch 7

正如你所说,对此有两种相反的观点.

它真正归结为的是,缓存条目可能应该在需要时以最精细的级别存储.我的意思是,如果你每次使用它时都使用你的词典中的每个条目,那么将它存储在字典级别.

如果您只使用字典中的一个项目,并且您没有走字典,那么将它们存储在单独的级别.

因此,如果将整个集合视为一个单元,则将其作为一个单元进行缓存.如果集合是随机访问的,并且一次只需要某些项目,则将其存储在单个单元的级别.