ASP.NET Cache

本文介绍了ASP.NET中的缓存技术,包括页面级输出缓存和用户控件级缓存。探讨了缓存技术如何帮助提高网站性能,减少系统开销,并详细解释了OutputCache指令的使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 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
### 解决PyCharm无法加载Conda虚拟环境的方法 #### 配置设置 为了使 PyCharm 能够成功识别并使用 Conda 创建的虚拟环境,需确保 Anaconda 的路径已正确添加至系统的环境变量中[^1]。这一步骤至关重要,因为只有当 Python 解释器及其关联工具被加入 PATH 后,IDE 才能顺利找到它们。 对于 Windows 用户而言,在安装 Anaconda 时,默认情况下会询问是否将它添加到系统路径里;如果当时选择了否,则现在应该手动完成此操作。具体做法是在“高级系统设置”的“环境变量”选项内编辑 `Path` 变量,追加 Anaconda 安装目录下的 Scripts 文件夹位置。 另外,建议每次新建项目前都通过命令行先激活目标 conda env: ```bash conda activate myenvname ``` 接着再启动 IDE 进入工作区,这样有助于减少兼容性方面的问题发生概率。 #### 常见错误及修复方法 ##### 错误一:未发现任何解释器 症状表现为打开 PyCharm 新建工程向导页面找不到由 Conda 构建出来的 interpreter 列表项。此时应前往 Preferences/Settings -> Project:...->Python Interpreter 下方点击齿轮图标选择 Add...按钮来指定自定义的位置。按照提示浏览定位到对应版本 python.exe 的绝对地址即可解决问题。 ##### 错误二:权限不足导致 DLL 加载失败 有时即使指定了正确的解释器路径,仍可能遇到由于缺乏适当的操作系统级许可而引发的功能缺失现象。特别是涉及到调用某些特定类型的动态链接库 (Dynamic Link Library, .dll) 时尤为明显。因此拥有管理员身份执行相关动作显得尤为重要——无论是从终端还是图形界面触发创建新 venv 流程均如此处理能够有效规避此类隐患。 ##### 错误三:网络连接异常引起依赖下载超时 部分开发者反馈过因网速慢或者其他因素造成 pip install 操作中途断开进而影响整个项目的初始化进度条卡住的情况。对此可尝试调整镜像源加速获取速度或是离线模式预先准备好所需资源包后再继续后续步骤。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值