ASP.NET Cache

来源:互联网 发布:random java 编辑:程序博客网 时间:2024/05/29 11:18

 1. INTRODUCTION
  大量的网站页面是采用动态的方式,根据用户提交的不同请求创建生成页面。正如我们所知的,动态页面有助于根据用户要求来提供定制的动态内容。动态页面也利于获取在数据库中每时每刻更新的资料。缺点是为每个用户请求生成同一页面增加了系统开销。
  ASP.NET 提供了缓存技术有助于我们最大程度地解决这个问题。它能缓存输出的页面,保存在存储器当中,缓存用户请求的内容。缓存的特点可以根据不同方式来定制的。
  本文主要介绍ASP.NET的缓存技术。介绍其使用方法,以及客户端缓存存在的问题。
  2. ASP.NET CACHE
  缓存是把应用程序中需要频繁、快速访问的数据保存在内存中的编程技术。ASP.NET提供三种主要形式的缓存:页面级输出缓存、用户控件级输出缓存(或称为片段缓存)和缓存API。输出缓存和片段缓存的优点是非常易于实现,在大多数情况下,使用这两种缓存就足够了。而缓存API则提供了额外的灵活性(实际上是相当大的灵活性),可用于在应用程序的每一层利用缓存。本文只介绍页面级缓存和用户控件级缓存。
  2.1. Page Caching
  作为最简单的缓存形式,输出缓存只是在内存中保留为响应请求而发送的 HTML 的副本。其后再有请求时将提供缓存的输出,直到缓存到期,这样,性能有可能得到很大的提高(取决于需要多少开销来创建原始页面输出 - 发送缓存的输出总是很快,并且比较稳定)。
  要实现页面输出缓存,只要将一条 OutputCache 指令添加到页面即可:
  <%@ OutputCache Duration="60" VaryByParam="*" %>
  如同其他页面指令一样,该指令应该出现在ASPX页面的顶部,即在任何输出之前。它支持五个属性(或参数),其中两个是必需的。
   Duration:必需属性。页面应该被缓存的时间,以秒为单位。必须是正整数。
   Location:指定应该对输出进行缓存的位置。如果要指定该参数,则必须是下列选项之一:Any、Client、Downstream、None、Server 或 ServerAndClient。
   VaryByParam:必需属性。Request 中变量的名称,这些变量名应该产生单独的缓存条目。"none" 表示没有变动。"*" 可用于为每个不同的变量数组创建新的缓存条目。变量之间用 ";" 进行分隔。 
   VaryByHeader:基于指定的标头中的变动改变缓存条目。
   VaryByCustom:允许在 global.asax 中指定自定义变动(例如,"Browser")。
  利用必需的 Duration 和 VaryByParam 选项的组合可以处理大多数情况。例如,如果您的产品目录允许用户基于 categoryID 和页变量查看目录页,您可以用参数值为 "categoryID;page" 的 VaryByParam 将产品目录缓存一段时间(如果产品不是随时都在改变,一小时还是可以接受的,因此,持续时间是 3600 秒)。这将为每个种类的每个目录页创建单独的缓存条目。每个条目从其第一个请求算起将维持一个小时。
  VaryByHeader 和 VaryByCustom 主要用于根据访问页面的客户端对页面的外观或内容进行自定义。同一个 URL 可能需要同时为浏览器和移动电话客户端呈现输出,因此,需要针对不同的客户端缓存不同的内容版本。或者,页面有可能已经针对 IE 进行了优化,但需要能针对 Netscape 或 Opera 完全降低优化(而不仅仅是破坏页面)。
  2.2. Fragment caching
  ASP.NET提供了部分缓存或区域缓存Web表单的功能。当希望在特定的页面上实现对缓存更多的控制时,可以使用该技术。
  为了指定应该被缓存的用户控件,我们利用 @OutputCache 指令,就象整个页面缓存的用法一样。
  <%@ OutputCache Duration=10 VaryByParam="*" %>
  该示例将缓存用户控件60秒,并且将针对查询字符串的每个变动、针对此控件所在的每个页面创建单独的缓存条目。
  <%@ OutputCache Duration="60" VaryByParam="none"
  VaryByControl="CategoryDropDownList" %>
  该示例将缓存用户控件60秒,并且将针对CategoryDropDownList控件的每个不同的值、针对此控件所在的每个页面创建单独的缓存条目。
  还可以通过设置属性Shared=”true”,让使用它的所有页面共享这个控件缓存。
  3. CONCLUSION AND SUGGESTION
  应该在应用程序的每一层都实现缓存。向数据层、业务逻辑层、UI 或输出层添加缓存支持。内存现在非常便宜 — 因此,通过以智能的方式在整个应用程序中实现缓存,可以获得很大的性能提高。
  缓存是一种无需大量时间和分析就可以获得“足够良好的”性能的方法。这里再次强调,内存现在非常便宜,因此,如果您能通过将输出缓存 30 秒,而不是花上一整天甚至一周的时间尝试优化代码或数据库就可以获得所需的性能,您肯定会选择缓存解决方案(假设可以接受 30 秒的旧数据)。缓存正是那些利用 20% 付出获得 80% 回报的特性之一,因此,要提高性能,应该首先想到缓存。不过,如果设计很糟糕,最终却有可能带来不良的后果,因此,您当然也应该尽量正确地设计应用程序。但如果您只是需要立即获得足够高的性能,缓存就是您的最佳选择,您可以在以后有时间的时候再尽快重新设计应用程序。
  ASP.NET缓存和IE缓存并不是同一个概念,IE缓存可能会导致错误发生,而且很难控制,可以考虑禁止IE缓存,而只采用ASP.NET缓存机制。
  针对我们的Web系统的特殊性,存在大量的页面针对不同的用户显示不同的数据,因此在采用ASP.NET缓存机制时,请格外小心。可以考虑在缓存机制使用时增加一些必要的参数。

  1. using System;
  2. using System.Collections;
  3. using System.Text.RegularExpressions;
  4. using System.Web;
  5. using System.Web.Caching;
  6. namespace Ycweb.Components
  7. {
  8.     public class SiteCache
  9.     {
  10.         private static readonly Cache _cache;
  11.         public static readonly int DayFactor;
  12.         private static int Factor;
  13.         public static readonly int HourFactor;
  14.         public static readonly int MinuteFactor;
  15.         static SiteCache()
  16.         {
  17.             DayFactor = 17280;
  18.             HourFactor = 720;
  19.             MinuteFactor = 12;
  20.             Factor = 5;
  21.             _cache = HttpRuntime.Cache;
  22.         }
  23.         private SiteCache()
  24.         {
  25.             _cache.Insert("""""""""""""");
  26.         }
  27.         public static void Clear()
  28.         {
  29.             IDictionaryEnumerator enumerator = _cache.GetEnumerator();
  30.             while (enumerator.MoveNext())
  31.             {
  32.                 _cache.Remove(enumerator.Key.ToString());
  33.             }
  34.         }
  35.         public static object Get(string key)
  36.         {
  37.             return _cache[key];
  38.         }
  39.         public static void Insert(string key, object obj)
  40.         {
  41.             Insert(key, obj, null, 1);
  42.         }
  43.         public static void Insert(string key, object obj, int seconds)
  44.         {
  45.             Insert(key, obj, null, seconds);
  46.         }
  47.         public static void Insert(string key, object obj, CacheDependency dep)
  48.         {
  49.             Insert(key, obj, dep, HourFactor * 12);
  50.         }
  51.         public static void Insert(string key, object obj, int seconds, CacheItemPriority priority)
  52.         {
  53.             Insert(key, obj, null, seconds, priority);
  54.         }
  55.         public static void Insert(string key, object obj, CacheDependency dep, int seconds)
  56.         {
  57.             Insert(key, obj, dep, seconds, CacheItemPriority.Normal);
  58.         }
  59.         public static void Insert(string key, object obj, CacheDependency dep, int seconds, CacheItemPriority priority)
  60.         {
  61.             if (obj != null)
  62.             {
  63.                 _cache.Insert(key, obj, dep, DateTime.Now.AddSeconds((double)(Factor * seconds)), TimeSpan.Zero, priority, null);
  64.             }
  65.         }
  66.         public static void Max(string key, object obj)
  67.         {
  68.             Max(key, obj, null);
  69.         }
  70.         public static void Max(string key, object obj, CacheDependency dep)
  71.         {
  72.             if (obj != null)
  73.             {
  74.                 _cache.Insert(key, obj, dep, DateTime.MaxValue, TimeSpan.Zero, CacheItemPriority.AboveNormal, null);
  75.             }
  76.         }
  77.         public static void MicroInsert(string key, object obj, int secondFactor)
  78.         {
  79.             if (obj != null)
  80.             {
  81.                 _cache.Insert(key, obj, null, DateTime.Now.AddSeconds((double)(Factor * secondFactor)), TimeSpan.Zero);
  82.             }
  83.         }
  84.         public static void Remove(string key)
  85.         {
  86.             _cache.Remove(key);
  87.         }
  88.         public static void RemoveByPattern(string pattern)
  89.         {
  90.             IDictionaryEnumerator enumerator = _cache.GetEnumerator();
  91.             Regex regex1 = new Regex(pattern, RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.IgnoreCase);
  92.             while (enumerator.MoveNext())
  93.             {
  94.                 if (regex1.IsMatch(enumerator.Key.ToString()))
  95.                 {
  96.                     _cache.Remove(enumerator.Key.ToString());
  97.                 }
  98.             }
  99.         }
  100.         public static void ReSetFactor(int cacheFactor)
  101.         {
  102.             Factor = cacheFactor;
  103.         }
  104.     }
  105. }
  106. 转载于:http://www.cnblogs.com/aspsir/archive/2006/07/27/461229.html
原创粉丝点击