设为首页 收藏本站
| 数控仿真 | 编程软件 | 技术文章 | 数控大赛 | 斐克科技 | 公路造价 | 文档备份 |
| 幸运之门彩票网 | 彩票论坛 | 彩票新闻 | 免费招聘 | 百科问吧 | 百姓族谱 | 小游戏网 |
“孑孓”是哪种动物的幼虫?
C#(CSharp) | VC/C++ | C++Builder | ASP(ASP.NET) | SQL Server | OpenGL | CMM | Web | NC | GIS | OS | 免费小游戏 | 彩票论坛
Google
联高软件 > 技术文章 > VB(ASP)/VB.NET > 使用ASP.NET 2.0 输出缓存替换的功能实现“甜圈缓存(DONUT CACHING)”
VB(ASP)/VB.NET | VC/VC++/VC.NET | C#(CSharp) | C++Builder | Java/JSP | EJB/J2EE |
使用ASP.NET 2.0 输出缓存替换的功能实现“甜圈缓存(Donut Caching)”

发表:联高软件www.legalsoft.com.cn,本文被阅读:1
【原文地址】 Tip/Trick: Implement "Donut Caching" with the ASP.NET 2.0 Output Cache Substitution Feature
【原文发表日期】 Tuesday, November 28, 2006 12:17 AM
一些背景:
ASP.NET中一个强大无比,但往往未被充分利用的功能是它丰富的缓存设施。ASP.NET的缓存功能允许你在服务端避免为来自客户端的每一个新请求做重复的工作,而是,你可以一次生成HTML内容或数据结构,然后在服务器端ASP.NET中缓存或存储其结果,在以后的web请求中重用这些结果。这可以极大地提高你应用的性能,降低对象数据库这样的关键后台资源的负载。
Steve Smith 几年前曾在MSDN上写过一篇很好的关于ASP.NET 1.1 中缓存的文章,讨论了ASP.NET 1.1 缓存功能的一些基本知识,并且对如何使用它们提供了一个很好的总结。如果你以前从没有用过ASP.NET 缓存的话,我建议你先读一下这篇文章,并对其中的每个特性都尝试一下。我也非常建议你观看一下ASP.NET 2.0 免费录像系列中的这个15分钟的关于ASP.NET缓存的"How Do I"录像,这个录像实战演示了ASP.NET 缓存。
ASP.NET 2.0添加了2个非常重要的改进,使得缓存功能更加完善:
1) 对SQL缓存失效的支持 - 这允许你在缓存的页面或数据结构所依赖的数据表或记录行被更新时,使缓存内容自动失效然后重新生成缓存内容。例如,你可以在一个电子商务网站上输出缓存你所有的产品列表网页,然后确信在数据库中的产品价格一旦有所变动,这些网页就会在下一个请求时重新生成,这样就不会向用户显示过期的价格数据了。
2) 输出缓存的替换 - 这个奇妙的特性允许你实现我有时称之为"甜圈缓存(donut caching)" 的功能,在这里,你输出缓存页面上的所有东西,但除了几个包含在缓存区域内的动态区域外。这允许你更积极地实现整页输出缓存,不用为了实现局部页面缓存而把你的页面分成多个.ascx用户文件。下面这个技巧/诀窍指南更好地解释了这个特性的促动因素以及其实现。
实战中的场景:
你要在你的网站上实现一个产品列单网页,在上面列出在某个指定产品分类下的所有产品。你也想要输出缓存这个网页,这样,你就不用在每次请求时都访问数据库。你在Products.aspx 网页的顶部用声明的方式添加一个 <%@ OutputCache %> 指令就可以很轻松地达成这个目的,该网页上包含一个绑定到从你的中间层返回的产品数据的 <asp:datalist> 控件。
注意下面该网页是如何设置输出缓存它的内容 100,000 秒或者直到northwind数据库中的 products数据表为新的价格数据所更新为止,在后面这个情形下,下一个请求时,它就会重新生成页面。OutputCache 指令还有一个VaryByParam 属性,它告诉 ASP.NET 为每个独特的categoryID 单独储存一份缓存页面。譬如,Products.aspx?categoryId=1,Products.aspx?categoryId=2等等各有一个单独的缓存页面。
Products.aspx:

<%@ Page Language="VB" MasterPageFile="~/Site.master" AutoEventWireup="false" CodeFile="Products.aspx.vb" Inherits="Products" %>
<%@ OutputCache Duration="100000" VaryByParam="CategoryID" SqlDependency="northwind:products" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<div class="catalogue">
<asp:DataList ID="DataList1" RepeatColumns="2" runat="server">
<ItemTemplate>

<div class="productimage">
<img src="images/productimage.gif" />
</div>

<div class="productdetails">

<div class="ProductListHead">
<%#Eval("ProductName")%>
</div>

<span class="ProductListItem">
<strong>Price:</strong>
<%# Eval("UnitPrice", "{0:c}") %>
</span>

</div>

</ItemTemplate>
</asp:DataList>

<h3>Generated @ <%=Now.ToLongTimeString()%></h3>
</div>
</asp:Content>

Products.aspx.vb:

Partial Class Products
Inherits System.Web.UI.Page
Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim products As New NorthwindTableAdapters.ProductsTableAdapter
DataList1.DataSource = products.GetProductsByCategoryID(Request.QueryString("categoryId"))
DataList1.DataBind()
End Sub
End Class

浏览器访问时,从服务器端返回下面这个页面:

注意,页面底部的时间戳每隔100,000秒,或者当products数据表里的价格数据被更新时,才会被更新。它将会被缓存起来以应付所有其他的 HTTP 请求,允许我们在生产服务器上每秒处理1000个请求,避免了不必要的数据库访问,从而使得访问的速度极快。
问题:
我们在上面的例子中将会遇到的一个问题,跟我们在页面右上方输出的欢迎消息和用户名字(在上面红圈中)有关。目前这是在我们的Site.Master母板页文件中通过使用一个新的ASP.NET 2.0 <asp:loginname> 控件来生成的,象这样:

<div class="header">
<h1>Caching Samples</h1>

<div class="loginstatus">
<asp:LoginName FormatString="Welcome {0}!" runat="server" />
</div>
</div>
我们将撞上的问题是,因为我们给我们的页面加了整页输出缓存,第一个访问网站的用户的名字将被保存到页面的缓存输出中,这意味着,在默认情形下,在初始请求之后的 100,000 秒之内访问网站的用户将收到一个错误的欢迎消息,更糟糕的是,显示的是错误的用户名字!
解决方案:
有2个方法可以解决这个问题。
第一个方案是将整个页面做成动态的,即去除顶层的 <%@ OutputCache %> 指令,对页面的内容重构,把所有可缓存的内容都封装在ASP.NET用户控件中,这些用户控件是通过 .ascx 文件来实现的。然后你在这些用户控件的每一个文件的顶部添加 <%@ OutputCache %> 指令,使得它们可以单独缓存。这避免了每次请求都需要访问数据库,确保了用户名字总是正确地输出的,因为用户名字不在缓存的用户控件区域里。这个方法目前在ASP.NET 1.1 里就可行,当然,在ASP.NET 2.0依然行之有效。
但这个方案的缺点是,为使缓存可行,它要求我们重构我们页面的编码和布局。但假如我们在页面上只有几个地方我们想要保持动态,这个重构会非常不方便。好消息是,ASP.NET 2.0 增加了对输出缓存替换块(Output Cache Substitution block )的支持,它提供了一个极其干净的方法来处理这个场景。
使用 <asp:substitution>控件的输出缓存替换块:
输出缓存替换块允许你OutputCache整个页面的输出,同时在HTML输出中留下几个动态区域标记来指明在以后的请求中你需要动态填充内容的地方(譬如,上面例子中的用户名消息)。我有时把这称为"甜圈缓存(donut caching)功能",因为外部的页面内容都是缓存的,只有页面内容流中间的几个孔(hole)是动态的。这与使用用户控件实现的局部页面缓存正好相反,因为在局部页面缓存的情形下,整个页面是动态的,中间的区域是缓存的。
你通过使用整页输出缓存的方式来实现输出缓存替换,使用与上面 Products.aspx 例子中完全一样的句法。然后,你可以通过在页面上添加 <asp:substitution> 控件来指明页面的哪些区域你需要动态地使用替换块来填充,象这样:

<div class="header">
<h1>Caching Samples</h1>

<div class="loginstatus">
<asp:Substitution ID="Substitution1" runat="server" MethodName="LoginText" />
</div>
</div>
<asp:Substitution> 控件与ASP.NET中的其他控件不同,它与 ASP.NET 的输出缓存注册了一个回调事件,当页面内容在后来的请求中从 ASP.NET输出缓存发出时,该事件会导致你的页面或母板页的一个静态方法的调用。这个静态方法在运行时会传进一个HttpContext 对象,它包含了ASP.NET Request, Response,User, Server,Session, Application等内在对象,然后你就可以使用它们来返回一个字符串,ASP.NET 会在内容发回客户端前自动把这个字符串注入到页面的相关区域里去。
譬如,在输出缓存的products.aspx 页面中,为处理上面这个我们需要动态输出欢迎消息的场景,我们只要简单地添加这个方法到我们的Site.Master后台代码文件中,然后让上面这个 <asp:substitution> 控件来调用:

Partial Class Site
Inherits System.Web.UI.MasterPage
Shared Function LoginText(ByVal Context As HttpContext) As String
Return "Hello " & Context.User.Identity.Name
End Function
End Class

这样,整个页面将被输出缓存,除了我们页面右上方的 <asp:substitution> 控件代表的欢迎消息的内容外。
很明显地,我们可以把这个进一步延伸,假如我们想要包括另外象用户他们的购物篮有多少样东西这样个人化的信息等。非常酷的是,页面上所有其他的内容仍然是保持完全缓存的,我们不用在后继请求里访问数据库来生成其内容,这意味着我们在单独一个服务器上每秒钟就可以处理成千个产品页。实际上,在请求中,不用生成页面上的任何控件,在以后的请求里,除了上面那个静态方法外,也没有编码会执行,这使得一切都快速无比。
使用Response.WriteSubstitution 方法的输出缓存替换块:
除了使用 <asp:substitution> 控件在页面上指定可替换的内容块外,你也可以使用 Response.WriteSubstitution 方法。这个方法接受一个HttpResponseSubstitutionCallback 方法的delegate对象为参数,你可以在你的应用的任何类里实现这个方法 (而不限于你后台类里的静态方法)。
<asp:substitution> 控件在内部使用这个方法来接连页面的后台类里的delegate方法。同样地,你也可以在你自己的控件或页面使用这个方法,以取得最大的控制和灵活性。
结论:
我还没有找到一个无法从ASP.NET缓存功能上受益的ASP.NET应用。因为ASP.NET支持整页输出缓存,局部页面输出缓存,以及现在的甜圈(donut)层次的缓存,这允许你根据任何参数或你需要的自定义逻辑来变换缓存内容,而现在又允许你在数据库改变时自动使得缓存内容失效并重新生成缓存内容,你不应该发现你自己再会建造一个用不上任何缓存的应用了。
我绝对建议你花点时间熟悉一下ASP.NET所有的缓存功能。想找到我完成的有关缓存的另外的例子的话,请下载我最近在ASP.NET Connections大会上做的技巧/诀窍讲座。下载内包括讲义和演示代码,说明如何使用整页缓存,局部页面缓存,替换块缓存(substitution block caching),以及SQL缓存失效(SQL Cache Invalidation)。
想阅读我写的其他ASP.NET技巧/诀窍博客帖子的话,请浏览我的ASP.NET技巧,诀窍和资源网页。
希望本文对你有所帮助,
 联高软件 > 技术文章 > VB(ASP)/VB.NET
·在ASP.NET中自动给URL地址加上超链接 (255)
·asp重定向 (286)
·不用 EOF 以加快记录循环(vb) (315)
·深入研究ASP中的Application和Session对象 (276)
·让Session对象在不同域名下实现共享 (1167)
·ASP和ASP.NET的MD5加密中文结果不同原因 (226)
·使用ASP访问XML文件 (1337)
·如何使用SQLSERVER2000中的XML功能 (181)
·正则表达式使用高级技巧之组的概念 (214)
·模板和泛型如何配合使用 (258)
·使用C#进行Word 2002和Excel 2002编程 (271)
·使用C#进行Reflection编程 (371)
·c#学习体会:使用 ref 和 out 传递数组 (336)
·在C#中使用代理的方式触发事件 (421)
·使用 HttpContext.RewritePath 来配合 Server.Transfer/Execute (413)
·在 ASP.NET 中使用计时器(Timer) (651)
·C# 2.0:使用匿名方法、迭代程序和局部类来创建优雅的代码 (227)
 最新文章
·如何使用SQLSERVER2000中的XML功能
·超强C#图片上传,加水印,自动生成缩略图
·C#中用SYSTEM.XML读写XML说明与代码
·C#取真实IP地址及分析
·C#+DIRECT3D9.0开发实例之月亮绕着地球转
·ASP程序员学习C#之超级攻略
·通过C#实现集合类纵览.NETCOLLECTIONS及
·C#开发WAP程序实例
·C#3.0中对象初始化器和集合初始化器
·C#3.0新特性速览
·ASP和ASP.NET的MD5加密中文结果不同原因
·CSS截取固定长度字符串
·简单实用的C#分词源代码(含词库素材下载
·C#高效分页代码(不用存储过程)
·SERVER.TRANSFER是在两个页面之间进行传
·一个克隆对象的C#基类
·C#语言FTP客户端代码
·递归枚举排列、组合的C#源码
·在C#.NET中跟踪代码的运行过程
·ASP.NET2.0中实现跨页面提交
·C#通用的数据操作类
·常用的C#数据检查类
·C#中的域(FIELD)和属性(PROPERTY)
·C#编码规范和编程好习惯
·C#编码好习惯
·用C#实现C/S模式下软件自动在线升级
·C#参考之访问关键字:BASE、THIS
·C#实现遗传算法模拟花朵的进化
·用C#的类实现数据结构的堆栈算法
·在C#中应用哈希表(HASHTABLE)
·用C#生成中文汉字验证码的基本原理
·C#.NET支付宝接口
·在C#中利用SHARPZIPLIB进行文件的压缩和
·程序员必须知道的SQLSERVER数据库优化技
·360度全方位比较C#和VB
·C#设计模式之建造者(BUILDER)模式示例源
·C#抽象工厂模式的几种实现方法及比较
·用设计模式固化C#程序
·数据结构与算法(C#实现)系列---二叉树
·在C#中建立复杂的、灵活的SQL查询/命令
·解读C#中的正则表达式
·对C#开发的两个基本原则的深入讨论
·正则表达式使用高级技巧之组的概念
·模板和泛型如何配合使用
·C#中提供的VB不支持的新特性
·关于C#在LUCENE.NET下的中文切词
·无废话C#设计模式之十:FLYWEIGHT
·无废话C#设计模式之十一:COMPOSITE
·无废话C#设计模式之十二:BRIDGE
·无废话C#设计模式之十三:DECORATOR
 热门文章
·程序员必须知道的SQLSERVER数据库优化技
·OpenGL 入门教程(一)
·OpenGL基础篇
·使用回调函数(VC & Delphi)
·OpenGL 入门教程(二)
·数控加工技术试题库
·C++Builder的一些技巧
·矩阵相乘的快速算法
·如何实现进程间数据通讯技术
·数控考题(二)
·矩阵求逆的快速算法
·数控试题(一)
·第一个三角形:NeHe的OpenGL第二课
·Universal Geospatial Data Exchange
·TServerSocket和TClientSocket的使用
·地理信息系统中的常规网络分析功能及相关
·选择与反馈 (OpenGL)
·数控车床加工编程典型实例分析
·函数调用的几个概念:_stdcall,_cdecl..
·OpenGL 入门教程(三)
·OpenGL 入门教程(六)
·Dijkstra 最短路径算法的一种高效率实现
·OpenGL 入门教程(四)
·应用程序的网上升级-VB
·自己绘制True type font字体
·OpenGL 入门教程(五)
·数控车床基本坐标关系及几种对刀方法比较
·数控机床标准M代码
·OpenGL 入门教程(七)
·关于VC多文档应用中OpenGL的使用
免费小游戏
宠物连连看

真人美女换装

美女脱衣服

美女胴体猜猜看

调戏床上美女

黄金矿工
“孑孓”是哪种动物的幼虫?
| 幸运之门 | 免费招聘 | 小游戏网 | 百科问吧 | 国际机票 | 我的信息 | 技术文章 | 文档备份 | 公路造价软件 | 联系我们 | 广告代理 | 媒体合作 | 免责条款 |
北京联高软件开发有限公司 1999-2008© 京ICP备05034864号 工商
地址:北京市海淀区中关村北二条13号中科科仪1号楼5层 地图
电话:010-82386887 010-62343002