众所周知,合理地使用@outputcache指令会提高Web应用程序的性能,关于@outputcache指令的普通使用,不在本文的讨论范围之内,不过为了后文的讲述,会在前面简单地提到。
 1@outputcache指令的语法如下所示:

<%@ OutputCache 
Duration
="#ofseconds" 
Location
="Any | Client | Downstream | Server | None | ServerAndClient " 
Shared
="True | False" 
VaryByControl
="controlname" 
VaryByCustom
="browser | customstring" 
VaryByHeader
="headers" 
VaryByParam
="parametername" 
CacheProfile
="cache profile name | ''" 
NoStore
="true | false" 
SqlDependency
="database/table name pair | CommandNotification" 
%>

    其中DurationVaryByParam是必须的,当然在用户控件中可以使用VaryByControl代替VaryByParam。如果不想使用VaryByParam的话可以设置其值为null,这样的话程序将只生成唯一的一个版本缓存。在这里我主要讲述的是VaryByCustom属性。
 
2、使用VaryByCustom属性。

使用VaryByCustom属性可以为程序定制不同的缓存版本,基本上可以定制任何您想要的缓存规则。想要使用VaryByCustom属性的话必须在Global.asax文件中override一个方法:public override string GetVaryByCustomString(HttpContext context, string arg)

其中参数context包含当前web的请求信息,而arg用于区分那个是当前请求的,是一个自定义字符串,因为所有使用VaryByCustom属性的outputcache指令都将调用这个方法,只有根据arg来区分。

缓存是根据这个方法返回字符串的不同而保存不同的版本,也就是说,如果这个方法返回的字符串有缓存的话就调用已有缓存,如果没有则生成一个新的缓存版本,以这个字符串作为键值保存在内存中。所以,在这个方法内部,您可以使用某种规则,使得用户访问的页面或者部分页面返回相同的字符串,那么在下次呈现这个页面或者部分页面的时候将调用缓存(在缓存没有过期的情况下)。

3、在GetVaryByCustomString方法中使用session

在某些系统中,显示的信息会根据某种分类的不同而不同,比如电子政务系统中,很多信息是按照部门来进行分类,所以需要按照其所在部门保存缓存信息。而在用户登陆后其部门信息一般是保存在Session内,所以必须在GetVaryByCustomString取得Session中的内容,下面将探讨取得Session的方法,在这个例子中缓存的版本将由类Class1的属性Filed确定。

如果在page页面中添加缓存指令@OutPutCache和其属性VaryByCustom后,在GetVaryByCustomString方法中获取Session会出错误,由于Global.asax文件中这种错误不会提示,所以很难看出,但是调试到这里的时候将会直接退出此方法(此处回返回同一个值,造成只能生成一个版本的缓存),所以不能在page页面中使用缓存指令时在GetVaryByCustomString方法中使用Session对象。

想在GetVaryByCustomString使用Session对象,必须是在用户控件中使用@OutPutCache才行,这是因为用户控件缓存的调用实际上是在页面高速缓存调用之前。下面演示怎么使用:

first.aspx页面内容:

<form id="Form1" method="post" runat="server">
            
<FONT face="宋体">
                
<asp:TextBox id="txtUser" style="Z-INDEX: 101; LEFT: 184px; POSITION: absolute; TOP: 104px" runat="server"></asp:TextBox>
                
<asp:Button id="btnSubmit" style="Z-INDEX: 102; LEFT: 184px; POSITION: absolute; TOP: 160px"
                    runat
="server" Text="提交" Width="152px"></asp:Button></FONT>
        
</form>

first.aspx.cs中提交按钮btnSubmit的实现:

        private void btnSubmit_Click(object sender, System.EventArgs e)
        
{
            Class1 c 
= new Class1();
            c.Filed 
= txtUser.Text.Trim().ToLower();
            Session[
"aa"]=c;
            Response.Redirect(
"secondPage.aspx");
        }

secondPage.aspx页面内容:

<form id="Form1" method="post" runat="server">
            
<FONT face="宋体">页面中当前时间:
                
<DIV><%=DateTime.Now.ToString()%></DIV>
                
<br>
                
<br>
                
<uc1:WebUserControl1 id="WebUserControl11" runat="server"></uc1:WebUserControl1></FONT>
        
</form>

WebUserControl1.ascx页面内容:

<%@ OutputCache Duration="60" VaryByParam="none"  VaryByCustom="aa" %>
<%@ Control Language="c#" AutoEventWireup="false" Codebehind="WebUserControl1.ascx.cs" Inherits="testOutPutCacheforSession.WebUserControl1" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%>
<hr>
用户控件中时间:
<DIV><%=DateTime.Now.ToString()%></DIV>
<hr>

Global.asax文件中的GetVaryByCustomString方法实现:

public override string GetVaryByCustomString(HttpContext context, string arg)
        
{        
            Class1 temp2 
= (Class1)Session["aa"];
            
return temp2.Filed;
        }

在这个例子中,在first.aspx的文本框输入一个字符串后,会把文本框中的内容保存在Session中,点击提交将会重定向到secondPage.aspx页,在secondPage.aspx页中用户控件的内容将会被缓存,缓存的版本由GetVaryByCustomString方法返回的值来确定,而GetVaryByCustomString返回的值从Session中得到,如果在文本框中输入的内容在缓存过期之前,输入前面输入过的字符串,那么用户控件的部分将使用缓存。当然,上面的例子可以简单地就在Session中保存一个字符串,而不是一个对象。

4
、缓存过期设置
使用输出缓存时,缓存的过期设置就尤为重要了,否则会产生让您苦笑不得的结果。但是这个又没有什么一成不变的方法,都得根据实际情况在做一些技巧上的设定。

但是,如果你使用SQL Server 7SQL Server 2000或者SQL Server 2005的话,那就好办多了,Microsoft提供了SqlDependency供您选择,SQL Server 7SQL Server 2000时基于轮询机制,而SQL Server 2005时基于通知机制,听起来通知机制好像要好一些:),

遗憾的是没有对Oracle进行支持,但是Oracle最新的版本Oracle 11G提供了自己的缓存机制,您只需要轻松地添加一些提示,Oracle将会让您得到满意的答案,这对很多人来说是个好消息。

posted on 2007-10-14 15:05  逐风者  阅读(1819)  评论(1编辑  收藏  举报