知识大全 如何利用缓存提高ASP.NET网站速度

Posted

篇首语:情况是在不断地变化,要使自己的思想适应新的情况,就得学习。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 如何利用缓存提高ASP.NET网站速度相关的知识,希望对你有一定的参考价值。

如何利用缓存提高ASP.NET网站速度  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  ASP NET提供三种主要形式的缓存 页面级输出缓存 用户控件级输出缓存(或称为片段缓存)和缓存API 输出缓存和片段缓存的优点是非常易于实现 在大多数情况下 使用这两种缓存就足够了 而缓存API则提供了额外的灵活性(实际上是相当大的灵活性) 可用于在应用程序的每一层利用缓存 本文全面介绍了这三种缓存技术在系统各层中的应用

  在ASP NET提供的许多特性中 缓存支持无疑是我最欣赏的特性 我这样说当然是有充分理由的 相比ASP NET的所有其他特性 缓存对应用程序的性能具有最大的潜在影响 利用缓存和其他机制 ASP NET开发人员可以接受使用开销很大的控件(例如 DataGrid)构建站点时的额外开销 而不必担心性能会受到太大的影响 为了在应用程序中最大程度地利用缓存 您应该考虑在所有程序级别上都实现缓存的方法

  Steve的缓存提示

  尽早缓存 经常缓存

  您应该在应用程序的每一层都实现缓存 向数据层 业务逻辑层 UI或输出层添加缓存支持 内存现在非常便宜 因此 通过以智能的方式在整个应用程序中实现缓存 可以获得很大的性能提高

  缓存可以防止许多过失

  缓存是一种无需大量时间和分析就可以获得 足够良好的 性能的方法 这里再次强调 内存现在非常便宜 因此 如果您能通过将输出缓存 秒 而不是花上一整天甚至一周的时间尝试优化代码或数据库就可以获得所需的性能 您肯定会选择缓存解决方案(假设可以接受 秒的旧数据) 缓存正是那些利用 %付出获得 %回报的特性之一 因此 要提高性能 应该首先想到缓存 不过 如果设计很糟糕 最终却有可能带来不良的后果 因此 您当然也应该尽量正确地设计应用程序 但如果您只是需要立即获得足够高的性能 缓存就是您的最佳选择 您可以在以后有时间的时候再重新设计应用程序

  页面级输出缓存

  作为最简单的缓存形式 输出缓存只是在内存中保留为响应请求而发送的HTML的副本 其后再有请求时将提供缓存的输出 直到缓存到期 这样 性能有可能得到很大的提高(取决于需要多少开销来创建原始页面输出 发送缓存的输出总是很快 并且比较稳定)

  实现

  要实现页面输出缓存 只要将一条OutputCache指令添加到页面即可

  <%@ OutputCache Duration= VaryByParam= * %>

  如同其他页面指令一样 该指令应该出现在ASPX页面的顶部 即在任何输出之前 它支持五个属性(或参数) 其中两个是必需的

  Duration 必需属性 页面应该被缓存的时间 以秒为单位 必须是正整数

  Location 指定应该对输出进行缓存的位置 如果要指定该参数 则必须是下列选项之一 Any Client Downstream None Server或ServerAndClient

  VaryByParam 必需属性 Request中变量的名称 这些变量名应该产生单独的缓存条目 none 表示没有变动 * 可用于为每个不同的变量数组创建新的缓存条目 变量之间用 ; 进行分隔

  VaryByHeader 基于指定的标头中的变动改变缓存条目

  VaryByCustom 允许在global asax中指定自定义变动(例如 Browser )

  利用必需的Duration和VaryByParam选项的组合可以处理大多数情况 例如 如果您的产品目录允许用户基于categoryID和页变量查看目录页 您可以用参数值为 categoryID;page 的VaryByParam将产品目录缓存一段时间(如果产品不是随时都在改变 一小时还是可以接受的 因此 持续时间是 秒) 这将为每个种类的每个目录页创建单独的缓存条目 每个条目从其第一个请求算起将维持一个小时

  VaryByHeader和VaryByCustom主要用于根据访问页面的客户端对页面的外观或内容进行自定义 同一个URL可能需要同时为浏览器和移动电话客户端呈现输出 因此 需要针对不同的客户端缓存不同的内容版本 或者 页面有可能已经针对IE进行了优化 针对Netscape或Opera则应取消这种优化功能 后一个例子非常普遍 我们将提供一个说明如何实现此目标的示例

  示例 VaryByCustom用于支持浏览器自定义

  为了使每个浏览器都具有单独的缓存条目 VaryByCustom的值可以设置为 browser 此功能已经内置在缓存模块中 并且将针对每个浏览器名称和主要版本插入单独的页面缓存版本

  <%@ OutputCache Duration= VaryByParam= None VaryByCustom= browser %>

  片段缓存 用户控件输出缓存

  更多选项

  除了上面提到的依赖项 我们还可以指定项的优先级(依次为low high NotRemovable 它们是在System Web Caching CacheItemPriority枚举中定义的)以及当缓存中的对象到期时调用的CacheItemRemovedCallback函数 大多数时候 默认的优先级已经足够了 缓存引擎可以正常完成任务并处理缓存的内存管理 CacheItemRemovedCallback选项考虑到一些很有趣的可能性 但实际上它很少使用 不过 为了说明该方法 我将提供它的一个使用示例

  CacheItemRemovedCallback示例

  System Web Caching CacheItemRemovedCallback callback = new System Web Caching CacheItemRemovedCallback (OnRemove);

  Cache Insert( key myFile null

  System Web Caching Cache NoAbsoluteExpiration

  TimeSpan Zero

  System Web Caching CacheItemPriority Default callback);

  

  public static void OnRemove(string key object cacheItem

  System Web Caching CacheItemRemovedReason reason)

  

  AppendLog( The cached value with key + key +

   was removed from the cache Reason: +

  reason ToString());

  

  该示例将使用AppendLog()方法中定义的任何逻辑来记录缓存中的数据到期的原因 通过在从缓存中删除项时记录这些项并记录删除的原因 您可以确定是否在有效地使用缓存或者您是否可能需要增加服务器上的内存 注意 callback是一个静态(在VB中为Shared)方法 建议使用该方法的原因是 如果不使用它 保存回调函数的类的实例将保留在内存中 以支持回调(对static/Shared方法则没有必要)

  该特性有一个潜在的用处 在后台刷新缓存的数据 这样用户永远都不必等待数据被填充 但数据始终保持相对较新的状态 但实际上 此特性并不适用于当前版本的缓存API 因为在从缓存中删除缓存的项之前 不触发或不完成回调 因此 用户将频繁地发出尝试访问缓存值的请求 然后发现缓存值为空 不得不等待缓存值的重新填充 我希望在未来的ASP NET版本中看到一个附加的回调 可以称为CachedItemExpiredBut

  NotRemovedCallback 如果定义了该回调 则必须在删除缓存项之前完成执行

  缓存数据引用模式

  每当我们尝试访问缓存中的数据时 都应该考虑到一种情况 那就是数据可能已经不在缓存中了 因此 下面的模式应该普遍适用于您对缓存的数据的访问 在这种情况下 我们假定已缓存的数据是一个数据表

  public DataTable GetCustomers(bool BypassCache)

  

  string cacheKey = CustomersDataTable ;

  object cacheItem = Cache[cacheKey] as DataTable;

  if((BypassCache) || (cacheItem == null))

  

  cacheItem = GetCustomersFromDataSource();

  Cache Insert(cacheKey cacheItem null

  DateTime Now AddSeconds(GetCacheSecondsFromConfig(cacheKey) TimeSpan Zero);

  

  return (DataTable)cacheItem;

  

  关于此模式 有以下几点需要注意

   ) 某些值(例如 cacheKey cacheItem和缓存持续时间)是一次定义的 并且只定义一次

   ) 可以根据需要跳过缓存 例如 当注册一个新客户并重定向到客户列表后 最好的做法可能就是跳过缓存 用最新数据重新填充缓存 该数据包括新插入的客户

   ) 缓存只能访问一次 这种做法可以提高性能 并确保不会发生NullReferenceExceptions 因为该项在第一次被检查时是存在的 但第二次检查之前就已经到期了

   ) 该模式使用强类型检查 C#中的 as 运算符尝试将对象转换为类型 如果失败或该对象为空 则只返回null(空)

   ) 持续时间存储在配置文件中 在理想的情况下 所有的缓存依赖项(无论是基于文件的 或是基于时间的 还是其他类型的依赖项)都应该存储在配置文件中 这样就可以进行更改并轻松地测量性能 我还建议您指定默认缓存持续时间 而且 如果没有为所使用的cacheKey指定持续时间 就让GetCacheSecondsFromConfig()方法使用该默认持续时间

  与本文相关的代码示例(CachedDemo msi 参见本书示例光盘)是一个helper类 它将处理上述所有情况 可以只书写一行或两行代码访问缓存的数据

  小结

  缓存可以使应用程序的性能得到很大的提高 因此在设计应用程序以及对应用程序进行性能测试时应该予以考虑 应用程序总会或多或少地受益于缓存 当然有些应用程序比其他应用程序更适合使用缓存 对ASP NET提供的缓存选项的深刻理解是任何ASP NET开发人员应该掌握的重要技巧

  缓存整个页面通常并不可行 因为页面的某些部分是针对用户定制的 不过 页面的其他部分是整个应用程序共有的 这些部分最适合使用片段缓存和用户控件进行缓存 此外 菜单和其他布局元素 尤其是那些从数据源动态生成的元素 也可以用这种方法进行缓存

  如果需要 可以按以下条件选择需要缓存的控件

  ( )某控件的属性已改变

  ( )由页面级输出缓存所支持的任何一种页面或控件状态改变

  一旦对某些控件进行了缓存 使用它们的几百个页面就可以共享这些控件 而不再需要为每个页面保留单独的控件缓存版本

  实现

  片段缓存使用的语法与页面级输出缓存一样 但其应用于用户控件( ascx文件)而不是Web窗体( aspx文件) 除了Location属性 对于OutputCache在Web窗体上支持的所有属性 用户控件也同样支持 用户控件还支持名为VaryByControl的OutputCache属性 该属性将根据用户控件(通常是页面上的控件 例如 DropDownList)的成员的值改变该控件的缓存 如果指定了VaryByControl 可以省略VaryByParam 最后 在默认情况下 对每个页面上的每个用户控件都单独进行缓存 不过 如果一个用户控件不随应用程序中的页面改变 并且在所有页面都使用相同的名称 则可以设置参数Shared的值为 true 该参数将使用户控件的缓存版本供引用该控件的所有页面使用

  示例

  <%@ OutputCache Duration= VaryByParam= * %>

  该示例将缓存用户控件 秒 并且将针对查询字符串的每个变动 针对此控件所在的每个页面创建单独的缓存条目

  <%@ OutputCache Duration= VaryByParam= none

  VaryByControl= CategoryDropDownList %>

  该示例将缓存用户控件 秒 并且将针对CategoryDrop

  DownList控件的每个不同的值 针对此控件所在的每个页面创建单独的缓存条目

  <%@ OutputCache Duration= VaryByParam= none VaryByCustom= browser

  Shared= true %>

  最后 该示例将缓存用户控件 秒 并且将针对每个浏览器名称和主要版本创建一个缓存条目 然后 每个浏览器的缓存条目将由引用此用户控件的所有页面共享(只要所有页面都用相同的ID引用该控件即可)

  缓存API 使用Cache对象

  页面级和用户控件级输出缓存的确是一种可以迅速而简便地提高站点性能的方法 但是在ASP NET中 缓存的真正灵活性和强大功能是通过Cache对象提供的 使用Cache对象 您可以存储任何可序列化的数据对象 基于一个或多个依赖项的组合来控制缓存条目到期的方式 这些依赖项可以包括自从某对象被缓存后经过的时间 自从某对象上次被访问后经过的时间 对文件或文件夹的更改以及对其他缓存对象的更改 在略作处理后还可以包括对数据库中特定表的更改

  在Cache中存储数据

  在Cache中存储数据的最简单的方法就是使用一个键为其赋值 就像HashTable或Dictionary对象一样

  Cache[ key ] = value ;

  这种做法将在缓存中存储项 同时不带任何依赖项 因此它不会到期 除非缓存引擎为了给其他缓存数据提供空间而将其删除 要包括特定的缓存依赖项 可使用Add()或Insert()方法 其中每个方法都有几个重载 Add()和Insert()之间的唯一区别是 Add()返回对已缓存对象的引用 而Insert()没有返回值(在C#中为空 在VB中为Sub)

  示例

  Cache Insert( key myXMLFileData new

  System Web Caching CacheDependency(Server MapPath( users xml )));

  该示例可将文件中的xml数据插入缓存 无需在以后请求时从文件读取 CacheDependency的作用是确保缓存在文件更改后立即到期 以便可以从文件中提取最新数据 重新进行缓存 如果缓存的数据来自若干个文件 还可以指定一个文件名的数组

  Cache Insert( dependentkey myDependentData new

  System Web Caching CacheDependency(new string[] new string[]

   key ));

  该示例可插入键值为 key 的第二个数据块(取决于是否存在第一个数据块) 如果缓存中不存在名为 key 的键 或者如果与该键相关联的对象已到期或被更新 则 dependentkey 的缓存条目将到期

  Cache Insert( key myTimeSensitiveData null

  DateTime Now AddMinutes( ) TimeSpan Zero);

  绝对到期 此示例将对受时间影响的数据缓存一分钟 一分钟过后 缓存将到期 注意 绝对到期和滚动到期(见下文)不能一起使用

  Cache Insert( key myFrequentlyAccessedData null

  System Web Caching Cache NoAbsoluteExpiration

  TimeSpan FromMinutes( ));

cha138/Article/program/net/201311/12353

相关参考

知识大全 ASP.NET缓存总结

ASP.NET缓存总结  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  一缓存概念缓存的好处类型 

知识大全 ASP.NET缓存介绍

ASP.NET缓存介绍  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!    ASPNET缓存   

知识大全 ASP.NET缓存分析

ASP.NET缓存分析  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  说到ASPNET缓存那就是

知识大全 ASP.NET缓存简述

ASP.NET缓存简述  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  以前对缓存的认识比较零碎最

知识大全 ASP.NET 输出缓存的移除

ASP.NET输出缓存的移除  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  ASPNET输出缓存

知识大全 ASP.NET2.0缓存技术

新手基础教程:ASP.NET2.0缓存技术  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  ASP

知识大全 ASP.NET缓存:方法分析和实践示例

ASP.NET缓存:方法分析和实践示例  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  尽早缓存经

知识大全 ASP.NET缓存方法分析和实践示例

ASP.NET缓存方法分析和实践示例  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  尽早缓存经常

知识大全 在asp.net 中实现维护数据缓存

在项目中我们经常会用到数据缓存也会在项目处理对缓存的维护但是有些时间我们需要人为的来维护这些缓存用下面的代码来实现   将缓存信息绑定到DataGrid上   privatevoidbindCache

知识大全 ASP.NET缓存初探 使用得当是关键

ASP.NET缓存初探使用得当是关键  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  文中对ASP