高级缓存技术

高级缓存技术
提高 Web 应用程序性能的一种方法是在内存中缓存静态内容。缓存内容的返回速度始终比新提供内容的速度快。但是,换来的是缓存的内容可能会过时。ASP.NET 1.x 支持几种缓存,包括:


 页面级别 — 每页可以作为一个整体块或根据用来访问该页的参数进行缓存。缓存页在一段固定时间之后过期。
 

 页面片段 — 如果使用用户控件(.ascx 文件)来构建页面,那么可以将用户控件独立于其他页面内容进行缓存。
 

 编程缓存 — 由于有了缓存 API,开发人员还可以缓存对象。缓存 API 具有独特的优势,提供一种在应该刷新缓存时创建不同类型依赖项的方式。
 

在 ASP.NET 2.0 中,页面级别的缓存机制已经扩展到了支持数据库依赖项。利用数据库缓存依赖项,缓存页可绑定到 SQL Server 数据库的一个特定表。当该表更改时,缓存自动过期。另外,开发人员现在可以使用缓存后替换来用刷新内容替换部分缓存内容。缓存后替换允许应用程序使用页面级别缓存,即使部分页面应当动态生成。

数据库缓存无效
对于大多数数据驱动的 Web 站点,缓存是一个麻烦的问题,特别是在要求缓存以及需要更新数据时。在 ASP.NET 1.x 中,可通过输入参数(查询字符串或 POST 参数)将页面缓存一定长度的时间和组织页面:
清单 5. ASP.NET 1.x输出缓存指令
 <%@ outputcache duration="3600" varybyparam="ProdID" %>
例如,清单 5 中的代码根据变量 ProdID 将页面在内存中缓存一个小时。上例中出现的问题是,如果在别处更新了相关的业务数据,应当如何处理。例如,考虑一个按产品 ID 缓存的产品目录页。如果在一个管理站点更新有关该产品的信息(例如,供应的数量或价格),就会将错误的数据缓存并显示给客户。对于以前版本的 ASP.NET,该问题的解决方案要求利用 Response.RemoveOutputCacheItem 手工地将该页从缓存中删除,或者等到 duration 时间到期并允许系统自动更新该页。

ASP.NET 2.0 通过支持数据库缓存依赖项解决了这个问题。当使用 SQL Server 7 和 2000 时可用表级通知,而 Microsoft SQL Server 将以更多的粒度级别来提供通知。例如,下列代码缓存一个产品页最多 1 个小时,但添加了第二个数据库表依赖项。

清单 6. ASP.NET 2.0 数据库缓存示例

<%@ outputcache duration="3600" varybyparam="ProdID" sqldependency="MyDatabase:Products" %> 

利用 sqldependency 新属性,如果对 Products 表有任何更改,那么缓存页将到期。sqldependency 属性必须引用一个 datasource,它在 web.config 文件中进行配置。datasource 识别数据库连接和必需的参数,以使依赖项通知工作。

自定义缓存依赖项

ASP.NET 2.0 配备一个 CacheDependency 实现,即 SQLCacheDependency 类,它支持 Microsoft SQL Server。实现一个新的缓存依赖项将是一个复杂的过程,但是由于有了 ASP.NET 2.0 的可扩展特性,这种实现是可能的。换句话说,可以创建自己的 CacheDependency 类来为数据库系统(例如 Oracle 或 Sybase)提供类似的功能。

缓存后替代

一些页面元素保持动态而大多数页将从缓存中受益,对于这种情况,ASP.NET 2.0 提供一种称为缓存后替代的功能。缓存后替代用来通知 ASP.NET 运行库缓存页呈现给用户之前应该重新评估该页上的某个特定元素。使用这种功能有两种方法:


 调用新方法 Response.writeSubstitution,将一个引用传递给替代回调函数。
 

 给 Web 页添加一个<asp:substitution> 控件并将 methodname 属性设置为回调函数的名称。
 

 对于任一种选项,应当给页面添加一个 @OutputCache 指令,指定依赖项的持续时间和位置。
 

实现缓存后替代
为了利用这种功能,可以创建能够识别缓存后替代的控件。AdRotator 控件就是一个这样的控件示例。清单 7 举例说明了这样一个页:


 检索 Pubs 数据库的作者表数据。
 

 将数据绑定到 GridView 控件。
 

 从一个 AdRotator 显示地址。
 

 在一个标签控件中显示创建该页的时间。
 

该示例中还添加了一个 <asp:substitution>控件(清单中的粗体行)。该控件的 methodname 属性设置为 uncachedUpdate(一种返回字符串输出的方法 — 在这种情况下为当前时间)。无论缓存什么内容,替代控件都将返回正确的时间。
清单 7. PostCache.ASPX 源代码

<%@ Page language="C#" Codefile="PostCache.ASPX.cs"
AutoEventWireup="true" Inherits="WebApplication1.PostCache" %>
<%@ outputcache duration="30" varybyparam="none" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
  <title>WebForm1</title>
</HEAD>
<body MS_POSITIONING="GridLayout">
  <form id="Form1" method="post" runat="server">
   <DIV style="DISPLAY: inline;
   Z-INDEX: 101; LEFT: 32px; WIDTH: 160px;
   POSITION: absolute; TOP: 24px; HEIGHT: 8px"
      align="right" ms_positioning="FlowLayout">
       this page was created at:
    </DIV>
    <ASP:Label id="CreatedTime"
     style="Z-INDEX: 102; LEFT: 200px; POSITION: absolute;
      TOP: 24px" runat="server" Width="120px" Height="16px">
   </ASP:Label>
  <ASP:substitution id="UpdatedTime" methodname="uncachedUpdate"
      style="Z-INDEX: 103; LEFT: 200px; POSITION: absolute;
      TOP: 48px" runat="server" Width="112px" Height="11px">
    </ASP:substitution>
    <DIV style="DISPLAY: inline; Z-INDEX: 104; LEFT: 32px;
      WIDTH: 160px; POSITION: absolute; TOP: 48px;
      HEIGHT: 16px" align="right" ms_positioning="FlowLayout">
        and last updated at:
    </DIV>
    <ASP:AdRotator id="Ads" style="Z-INDEX: 105; LEFT: 312px;
      POSITION: absolute; TOP: 16px" runat="server"
      Width="80px" Height="60px" AdvertisementFile="img/Ads.xml">
    </ASP:AdRotator>
  </form>
该页的代码隐藏文件包含支持 uncachedUpdate 方法的缓存后替代所必需的事件。请注意,Page_Load 方法报告加载该页的时间,因此我们可以确定缓存发生的时间。
清单 8. PostCache.ASPX.cs
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
 namespace WebApplication1 {
public class PostCache : System.Web.UI.Page  {
  protected System.Web.UI.WebControls.Label CreatedTime;
  protected System.Web.UI.WebControls.Label UpdatedTime;
  protected System.Web.UI.WebControls.AdRotator Ads;
  private void InitializeComponent()  {
    this.Load += new System.EventHandler(this.Page_Load);

  private void Page_Load(object sender, System.EventArgs e) {
    CreatedTime.Text = DateTime.Now.ToShortTimeString();  
  }
  protected String uncachedUpdate()  {
    return DateTime.Now.ToShortTimeString();
当前使用的缓存后替代
图 6 显示 PostCache 页的输出结果。首次运行应用程序,我们可以看到“创建页”时间和“最后更新”时间是相同的。
 

图 6. PostCache.ASPX 的输出结果
连续调用同一个页面,我们可以看到缓存后替代的效果。虽然页面创建时间和图像保持不变,但最后更新时间有变化。
 

图 7. 第二次请求的缓存后输出结果由于缓存指令,创建时间和 adRotator 图像都保持不变。该页缓存了 30 秒。一旦时间到期,下次请求时创建时间和 adRotator 都将更新。但是,<asp:substitution> 控件(调用 uncachedUpdate() 方法)在每次请求页面时都将更新,而不管其缓存状态。通过正确操作缓存后替代,开发人员可以通过只更新其页面的动态内容以显著提高其 Web 应用程序性能。结合数据库缓存无效和异步页更新,用 ASP.NET 2.0 开发的 Web 应用程序将消除由 Web 的传统请求和响应体系结构所施加的许多限制。
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值