ASP.NET缓存:方法和最佳实践




  尽早缓存Cache;经常缓存Cache
  
  您应该在应用层都实现缓存Cache向数据层、业务逻辑层、UI 或输出层添加缓存Cache支持内存现在非常便宜 — 因此通过以智能方式在整个应用中实现缓存Cache可以获得很大性能提高
  
  缓存Cache可以掩盖许多过失
  
  缓存Cache是种无需大量时间和分析就可以获得“足够良好”性能思路方法这里再次强调内存现在非常便宜因此如果您能通过将输出缓存Cache 30 秒而不是花上整天甚至时间尝试优化代码或数据库就可以获得所需性能您肯定会选择缓存Cache解决方案(假设可以接受 30 秒旧数据)缓存Cache正是那些利用 20% 付出获得 80% 回报特性的因此要提高性能应该首先想到缓存Cache不过如果设计很糟糕最终却有可能带来不良后果因此您当然也应该尽量正确地设计应用但如果您只是需要立即获得足够高性能缓存Cache就是您最佳选择您可以在以后有时间时候再尽快重新设计应用
  
  页面级输出缓存Cache
  
  作为最简单缓存Cache形式输出缓存Cache只是在内存中保留为响应请求而发送 HTML 副本其后再有请求时将提供缓存Cache输出直到缓存Cache到期这样性能有可能得到很大提高(取决于需要多少开销来创建原始页面输出 - 发送缓存Cache输出总是很快并且比较稳定)
  
  实现
  
  要实现页面输出缓存Cache只要将条 OutputCache 指令添加到页面即可
  
  <%@ OutputCache Duration="60" VaryByParam="*" %>
  
  如同其他页面指令该指令应该出现在 ASPX 页面顶部即在任何输出的前它支持 5个属性(或参数)其中两个是必需
  
  Duration
  
  必需属性页面应该被缓存Cache时间以秒为单位必须是正整数
  
  Location
  
  指定应该对输出进行缓存Cache位置如果要指定该参数则必须是下列选项的:Any、Client、Downstream、None、Server 或 ServerAndClient
  
  VaryByParam
  
  必需属性Request 中变量名称这些变量名应该产生单独缓存Cache条目"none" 表示没有变动"*" 可用于为每个区别变量创建新缓存Cache条目变量的间用 ";" 进行分隔
  
  VaryByHeader
  
  基于指定标头中变动改变缓存Cache条目
  
  VaryByCustom
  
  允许在 global.asax 中指定自定义变动(例如"Browser")
  
  利用必需 Duration 和 VaryByParam 选项组合可以处理大多数情况例如如果您产品目录允许用户基于 categoryID 和页变量查看目录页您可以用参数值为 "categoryID;page" VaryByParam 将产品目录缓存Cache段时间(如果产品不是随时都在改变小时还是可以接受因此持续时间是 3600 秒)这将为每个种类每个目录页创建单独缓存Cache条目每个条目从其第个请求算起将维持个小时
  
  VaryByHeader 和 VaryByCustom 主要用于根据访问页面客户端对页面外观或内容进行自定义个 URL 可能需要同时为浏览器和移动电话客户端呈现输出因此需要针对区别客户端缓存Cache区别内容版本或者页面有可能已经针对 IE 进行了优化但需要能针对 Netscape 或 Opera 完全降低优化(而不仅仅是破坏页面)个例子非常普遍我们将提供个介绍说明如何实现此目标举例:
  
  举例:VaryByCustom 用于支持浏览器自定义
  
  为了使每个浏览器都具有单独缓存Cache条目VaryByCustom 值可以设置为 "browser"此功能已经内置在缓存Cache模块中并且将针对每个浏览器名称和主要版本插入单独页面缓存Cache版本
  
  <%@ OutputCache Duration="60" VaryByParam="None" VaryByCustom="browser" %>
  
  片段缓存Cache用户Control控件输出缓存Cache
  
  缓存Cache整个页面通常并不可行页面某些部分是针对用户定制不过页面其他部分是整个应用共有这些部分最适合使用片段缓存Cache和用户Control控件进行缓存Cache菜单和其他布局元素尤其是那些从数据源动态生成元素也应该用这种思路方法进行缓存Cache如果需要可以将缓存CacheControl控件配置为基于对其Control控件(或其他属性)更改或由页面级输出缓存Cache支持任何其他变动进行改变使用同组Control控件几百个页面还可以共享那些Control控件缓存Cache条目而不是为每个页面保留单独缓存Cache版本
  
  实现
  
  片段缓存Cache使用语法和页面级输出缓存Cache但其应用于用户Control控件(.ascx 文件)而不是 Web 窗体(.aspx 文件)除了 Location 属性对于 OutputCache 在 Web 窗体上支持所有属性用户Control控件也同样支持用户Control控件还支持名为 VaryByControl OutputCache 属性该属性将根据用户Control控件(通常是页面上Control控件例如DropDownList)成员值改变该Control控件缓存Cache如果指定了 VaryByControl可以省略 VaryByParam最后在默认情况下对每个页面上每个用户Control控件都单独进行缓存Cache不过如果个用户Control控件不随应用页面改变并且在所有页面都使用相同名称则可以应用 Shared="true" 参数该参数将使用户Control控件缓存Cache版本供所有引用该Control控件页面使用
  
  举例
  
  <%@ OutputCache Duration="60" VaryByParam="*" %>
  
  该举例将缓存Cache用户Control控件 60 秒并且将针对查询每个变动、针对此Control控件所在每个页面创建单独缓存Cache条目
  
  <%@ OutputCache Duration="60" VaryByParam="none"
  
  VaryByControl="CategoryDropDownList" %>
  
  该举例将缓存Cache用户Control控件 60 秒并且将针对 CategoryDropDownList Control控件每个区别值、针对此Control控件所在每个页面创建单独缓存Cache条目
  
  <%@ OutputCache Duration="60" VaryByParam="none" VaryByCustom="browser"
  
  Shared="true %>
  
  最后该举例将缓存Cache用户Control控件 60 秒并且将针对每个浏览器名称和主要版本创建个缓存Cache条目然后每个浏览器缓存Cache条目将由引用此用户Control控件所有页面共享(只要所有页面都用相同 ID 引用该Control控件即可)
  
  页面级和用户Control控件级输出缓存Cache确是种可以迅速而简便地提高站点性能思路方法但是在 ASP.NET 中缓存Cache真正灵活性和强大功能是通过 Cache 对象提供使用 Cache 对象您可以存储任何可序列化数据对象基于个或多个依赖项组合来控制缓存Cache条目到期方式这些依赖项可以包括自从项被缓存Cache后经过时间、自从项上次被访问后经过时间、对文件和/或文件夹更改以及对其他缓存Cache项更改在略作处理后还可以包括对数据库中特定表更改
  
  在 Cache 中存储数据
  
  在 Cache 中存储数据最简单思路方法就是使用个键为其赋值就像 HashTable 或 Dictionary 对象样:
  
  Cache["key"] = "value";
  
  这种做法将在缓存Cache中存储项同时不带任何依赖项因此它不会到期除非缓存Cache引擎为了给其他缓存Cache数据提供空间而将其删除要包括特定缓存Cache依赖项可使用 Add 或 Insert 思路方法其中每个思路方法都有几个重载Add 和 Insert 的间区别是Add 返回对已缓存Cache对象引用而 Insert 没有返回值(在 C# 中为空在 VB 中为 Sub)
  
  举例
  
  Cache.Insert("key", myXMLFileData,
  
  .Web.Caching.CacheDependency(Server.MapPath("users.xml")));
  
  该举例可将文件中 xml 数据插入缓存Cache无需在以后请求时从文件读取 CacheDependency 作用是确保缓存Cache在文件更改后立即到期以便可以从文件中提取最新数据重新进行缓存Cache如果缓存Cache数据来自若干个文件还可以指定个文件名
  
  Cache.Insert("dependentkey", myDependentData,
  
  .Web.Caching.CacheDependency( {},
  
  {"key"}));
  
  该举例可插入键值为 "key" 第 2个数据块(取决于是否存在第个数据块)如果缓存Cache中不存在名为 "key" 或者如果和该键相关联项已到期或被更新则 "dependentkey" 缓存Cache条目将到期
  
  Cache.Insert("key", myTimeSensitiveData, null,
  
  DateTime.Now.AddMinutes(1), TimeSpan.Zero);
  
  绝对到期:此举例将对受时间影响数据缓存Cache分钟分钟过后缓存Cache将到期注意绝对到期和滑动到期(见下文)不能起使用
  
  Cache.Insert("key", myFrequentlyAccessedData, null,
  
  .Web.Caching.Cache.NoAbsoluteExpiration,
  
  TimeSpan.FromMinutes(1));
  
  滑动到期:此举例将缓存Cache些频繁使用数据数据将在缓存Cache中直保留下去除非数据未被引用时间达到了分钟注意滑动到期和绝对到期不能起使用
  
  更多选项
  
  除了上面提到依赖项我们还可以指定项优先级(依次为 low、high、NotRemovable它们是在 .Web.Caching.CacheItemPriority 枚举中定义)以及当缓存Cache中项到期时 CacheItemRemovedCallback 大多数时候默认优先级已经足够了 — 缓存Cache引擎可以正常完成任务并处理缓存Cache内存管理CacheItemRemovedCallback 选项考虑到些很有趣可能性但实际上它很少使用不过为了介绍说明该思路方法我将提供它个使用举例:
  
  CacheItemRemovedCallback 举例
  
  .Web.Caching.CacheItemRemovedCallback callback = .Web.Cac
Tags: 

延伸阅读

最新评论

发表评论