asp.net缓存说明及示例
1.页面缓存:
页面输出缓存用于缓存页面呈现的所有内容(当在浏览器中选择查看源码能看的所有内容)到内存中.
注:页面输出缓存作用于整个页面.
1.1部分页面缓存通过只缓存页面上的一个特定区域来解决这个问题.利用部分页面缓存,可以对页面的不同区域应用
不同的缓存策略.
1.2当一个页面被缓存时,被请求时的页面内容并不会每次都重新生成.每次请求一个页面,对应到页面的.NET类也不会
执行.对于每一个请求页面的用户,页面呈现的内容都会缓存.
((((((((((((((((((((((((((((((((((((((((((((((((
缓存的存放的位置:
页面可在多个位置缓存.而默认情况下,页面可能缓存在浏览器,任意的代理服务器端以及Web服务器.
(注:当代理服务器端或浏览器缓存页面时,它们总是缓存整个页面.)
也可以在OutputCache的Location属性来设置缓存存放位置。Any,Client,DownStream,None,ServerAndClient.
))))))))))))))))))))))))))))))))))))))))))))))))
1.3缓存之基于自定义函数变化的输出缓存
VaryByCustom可以给它指定一个自定义函数来决定何时生成不同的页面缓存版本.
可以在Global.asax全局程序类文件中重写GetVaryByCustomString()方法来创建自定义函数.
即根据GetVaryByCustomString()方法返回的string生成相应此string的页面缓存版本.
1.4创建页面输出缓存文件依赖
即可以在一个缓存页面和硬盘上的一个文件(或一组文件)之间创建一个依赖。当文件修改时缓存页面自动失效
并重新在下次页面请求时生成。
1.5使用编程方式设置输出缓存过期
使用Response.RemoveOutputCacheItem()方法,只接受一个“虚拟绝对”路径,即要用Page.ResoveUrl()方法来
转换~符号为应用程序的根路径。
HttpResponse.RemoveOutputCacheItem(Page.ResolveUrl("~/实现使用编程方式设置页面输出缓存过 期/MovieList.aspx"));
Response.Redirect("~/实现使用编程方式设置页面输出缓存过期/MovieList.aspx");
1.6若要删除多个页面,需要创建一个所谓的键依赖(Key dependency)。一个键依赖用于在缓存中的项目之间建立依赖。当第二个项目移除时,第一个项目也会被自动移除。
先插入Cache.Insert("Movies", DateTime.Now);
Response.AddCacheItemDependency("Movies");
再在另一个页面
Cache.Remove("Movies");
Response.Redirect("~/实现使用编程方式设置页面输出缓存过期/MovieListKeyDependency.aspx");
*****************************************************************************************
上面介绍的是页面的全部缓存输出
下面介绍的是使用部分页面缓存
*****************************************************************************************
2使用缓存后替换有两种方式:
2.1声明方式一定要使用Substitution控件
Substitution 控件指定输出缓存的网页上不进行缓存的部分。使用 Substitution 控件可以在输出缓存的网页上指定希望用动态内容 替换控件的部分。
Substitution 控件将动态内容插入到缓存页中。Substitution 控件不会呈现任何标记。您需要将该控件绑定到页上或父用户控件上 的方法中。您要自行创建静态方法,以返回要插入到页中的任何信息。由 Substitution 控件调用的方法必须符合下面的标准:
此方法被定义为静态方法(在 Visual Basic 中为共享方法)。
此方法接受 HttpContext 类型的参数。
此方法返回 String 类型的值。
即此方法的签名为:public static string MethodName(HttpContext context){}
(注:Substitution的属性MethodName返回的string可以支持Html编码哦。)
ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.chs/dv_aspnetcon/html/fd47d5f3-1ede-4096-96eb-8d9c96012451.htm
2.2.可用编程方式Response.WriteSubstitution()
Substitution控件的时间是:
<% Response.WriteSubstitution(GetTime);%>
2.3使用用户控件缓存(缓存后替换只在处理字符串文本和HTML时比较合适,若望处理更复杂的部分页面缓存,则应该利用用户控件)
<%@ Control Language="C#" ClassName="Movies" %>
<%@ OutputCache Duration="60" VaryByParam="none" %>
用户控件时间:<%= DateTime.Now.ToString("T") %><hr />
<asp:GridView ID="grdMovies" DataSourceID="srcMovies" runat="server" />
<asp:SqlDataSource ID="srcMovies" ConnectionString="<%$ ConnectionStrings:Movies %>" SelectCommand="SELECT Title,Director FROM Movies" runat="server" />
(注:用户控件中的OutputCache有个Shared属性,若设为true则此用户在多个页面中使用时,都是只缓存一个页面版本.)
用编程方式处理用户控件缓存
************************************************************************************
4.使用DataSource缓存(即可以设置DataSource属性来实现)
4.1使用数据源控件缓存的一个好处是数据源控件可以在数据更新时自动重新载入数据,且可以在多个页面间共享相同的数据.
<asp:GridView ID="grdMovies" DataSourceID="srcMovies" runat="server" />
<asp:SqlDataSource ID="srcMovies" EnableCaching="true" CacheDuration="60" SelectCommand="SELECT * FROM Movies" ConnectionString="<%$ ConnectionStrings:Movies %>" runat="server" />
4.2使用Sliding缓存过期策略
需要缓存大量数据,则使用sliding过期策略比绝对缓存过期策略要更合理.当使用sliding缓存过期策略时,除非数据在指定时间段内
再次被请求访问,否则缓存就会丢失.(也就是说用户不停的访问时,其过期间隔还是这么多)
<asp:GridView ID="grdMovies" DataSourceID="srcMovies" runat="server" />
<asp:SqlDataSource ID="srcMovies" EnableCaching="true" CacheExpirationPolicy="Sliding" CacheDuration="15" SelectCommand="SELECT * FROM Movies" ConnectionString="<%$ ConnectionStrings:Movies %>" runat="server" OnSelecting="srcMovies_Selecting" />
(小技巧:检测电影的缓存是否失效可实现SqlDataSource数据源控件的Selecting事件,因此事件是在从数据库获得电影时被调用,若从内存中获得时不会被调用.)
4.3其实ObjectDataSource控件与SqlDataSource控件一样的缓存属性.
5.使用数据缓存
在内部,Asp.Net Framework包含的所有不同的缓存机制都使用了Cache对象.也就是说,Cache对象是Asp.Net中所有缓存的根本机制.
对于每一个Asp.Net应用程序,都会创建了个Cache对象的实例.添加到缓存中的任何项目都能被其他页面,控件或包含在相同的应用程序(虚拟目录)中的组件访问.
5.1使用缓存API
即Cache对象,其有属性及相应的方法。
6.使用SQL缓存依赖(就象trigger一样,数据库一更新就把缓存给更新)
ASP.NET2.0 Framework新增的一个非常强大的功能是SQL缓存依赖.该功能允许在指定的数据库数据修改时,自动地重新载入缓存的数据.
ASP.NET Framework支持的SQL缓存依赖使得使用缓存时可以充分利用缓存,并陈旧数据最少.当使用SQL缓存依赖时,可以自动监测指定数据库中的数据是否变更,并刷新缓存中的数据.
6.1使用拉SQL缓存依赖
拉SQL缓存依赖是最灵活的SQL缓存依赖类型,所以对大多数应用程序来说,推荐使用拉类型SQL缓存依赖可以使用拉SQL缓存依赖来检测数据库表的修改.
拉SQL缓存依赖就是:使用数据库trigger.当表被修改时,trigger被触发,名为AspNet_SqlCacheTablesForChangeNotification的数据表的一行数据将被更新,来记录被修改的情况.
具体内部运行是:ASP.MET Framework使用一个后台线程,来定期拉数据库表的修改信息.如果有修改,则依赖于数据表的缓存项目从缓存中移除.
6.2配置拉SQL缓存依赖
在使用拉SQL缓存依赖之前,必须执行下面两步骤:
1).必须对一个或多个数据库表启用SQL缓存依赖.
6.2.1.1执行下面的命令可启用test数据库的SQL缓存依赖:
aspnet_regsql -C "Data Source=localhost;Integrated Security=True;Initial Catalog=test" -ed
或
aspnet_regsql -C "Server=.;Integrated Security=True;Database=pubs" -ed
(此命令将创建AspNet_SqlCacheTablesForChangeNotification数据表,并添加一组存储过程到链接字符串指定的数据库)
6.2.1.2启用一个数据库之后,就可以用如下命令启用特定表的SQL缓存依赖:(启用tbTest数据表的SQL缓存依赖)
aspnet_regsql -C "Data Source=localhost;Integrated Security=True;Initial Catalog=test" -et -t tbTest
或
aspnet_regsql -C "Server=localhost;Integrated Security=True;Database=pubs" -et -t authors
(此命令为pubs数据库authors数据表的SQL缓存依赖.它会给authors表创建一个新的trigger,并添加一行新记录到
AspNet_SqlCacheTablesForChangeNotification表中)
2).必须在Web配置文件中配置SQL缓存依赖.
<caching>
<sqlCacheDependency enabled="true" pollTime="1000">
<databases>
<add name="MyPubs" connectionStringName="Pubs"/>
</databases>
</sqlCacheDependency>
</caching>
3).最后应用是要在OutputCache的属性SqlDependency设置如:SqlDependency="MyDatabase:Movies"
<%@ OutputCache Duration="8888" VaryByParam="none" SqlDependency="MyPubs:authors,title,***" %>
<%= DateTime.Now.ToString("T") %><hr />
<asp:GridView ID="grdAuthors" runat="server" DataSourceID="srcAuthors" />
<br />
<asp:SqlDataSource ID="srcAuthors" runat="server" ConnectionString="<%$ ConnectionStrings:Pubs %>" SelectCommand="SELECT au_lname,au_fname,address FROM authors" />
6.3使用推SQL缓存依赖
在使用MS SQL Server05时,除了拉SQL缓存依赖,还可以使用推SQL缓存依赖.即MS SQL Server05包含一个名为查询通知的功能,它在后台使用MS SQL Server 05 的Service Broker.这个Service Broker可以在数据库中的数据变更时自动给应用程序发送一个消息.(即推SQL缓存依赖是数据库有更改时就发消息通知应用程序,而拉SQL缓存依赖是应用程序在一段时间间隔里向数据库的特殊表查看是否数据库有没改变).
(注:推SQL缓存依赖有诸多的限制如:查询的表名要两部分如dbo.Movies而不是Movies,等N多限制)
6.4配置推SQL缓存依赖
1).必须配置数据库启用SQL Server 2005 Service Broker.
6.4.1.1在MS sql server 05中随便建立下列查询来查看Service Broker是否已经为特定的数据库激活
select name,is_broker_enabled from sys.databases
6.4.1.2若Service Broker还没有启用,则要执行Alter Database命令来启用它,如:
Alter Database TestDb Set Enable_Broker
6.4.1.3最后,Asp.Net进程必须有足够的权限来订阅查询通知.(当一个Asp.Net页面由IIS处理,页面在NETWORK SERVICE账号 (WinServer03)或ASPNET账号(对于其他系统,如Win XP)上下文中执行.
给test服务器上的本地ASPNET账号赋予需要的权限:
GRANT SUBSCRIBE QUERY NOTIFICATIONS TO "test\ASPNET"
2).必须配置应用程序开始监听通知.
6.4.2.1在应用程序可以接收到变更通知之前,必须启用查询通知监听器.在Global.asax文件中启用监听器:
void Application_Start(object sender, EventArgs e)
{
// 在应用程序启动时运行的代码
string conString = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["Test"].ConnectionString;
SqlDependency.Start(conString);
}
//只需要在Web.config中添加个数据库连接字符串即可
6.4.2.2最后使用推SQL缓存依赖实现对页面输出缓存(代码如下所示:)
<%@ Page Language="C#" %>
<%@ OutputCache Duration="888" VaryByParam="none" SqlDependency="CommandNotification" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Push SQL OutputCache</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<%= DateTime.Now.ToString("T") %><hr />
<asp:GridView ID="grdTest" runat="server" DataSourceID="srcTest" />
<br />
<asp:SqlDataSource ID="srcTest" runat="server" ConnectionString="<%$ ConnectionStrings:Test %>" SelectCommand="SELECT id,name FROM dbo.tbTest" />
</div>
</form>
</body>
</html>
SqlCacheDependency 类监视输出缓存所依赖的数据库中的表,因此当更新表中的项时,使用基于表的轮询时将从缓存中移除这些项。将通知(在 Microsoft SQL Server 2005 中)与 CommandNotification 值一起使用时,最终将使用 SqlDependency 类向 SQL Server 2005 服务器注册查询通知。
注意
SqlDependency 属性的 CommandNotification 值仅在网页 (.aspx) 中有效。用户控件只能将基于表的轮询用于 @ OutputCache 指令。
6.4.2.3对DataSource缓存使用推SQL缓存依赖(实例代码:)
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void srcAuthors_Selecting(object sender, SqlDataSourceSelectingEventArgs e)
{
this.lblMsg.Text = "正在从数据库中查询数据";
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>无标题页</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="lblMsg" runat="server" />
<hr />
<asp:GridView ID="grdTest" runat="server" DataSourceID="srcTest" />
<asp:SqlDataSource ID="srcTest" runat="server" ConnectionString="<%$ ConnectionStrings:Test %>" SelectCommand="SELECT id,name FROM dbo.tbTest"
EnableCaching="true" SqlCacheDependency="CommandNotification" OnSelecting="srcAuthors_Selecting" />
</div>
</form>
</body>
</html>
6.4.2.3对数据缓存使用推SQL缓存依赖(实例:)
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Web.Configuration" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
void Page_Load()
{
DataTable dtTest = (DataTable)Cache["dtTest"];
if (dtTest==null)
{
Trace.Warn("正在数据库中获取数据");
string conString = WebConfigurationManager.ConnectionStrings["Test"].ConnectionString;
SqlDataAdapter da = new SqlDataAdapter("SELECT id,name FROM tbTest", conString);
//进行推SQL缓存依赖设置
SqlCacheDependency sqlDepend = new SqlCacheDependency(da.SelectCommand);
//要注意是Fill之前就绑定了缓存依赖
da.Fill(dtTest);
Cache.Insert("dtTest", dtTest, sqlDepend);
}
grdTest.DataSource = dtTest;
grdTest.DataBind();
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>无标题页</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="lblMsg" runat="server" />
<asp:GridView ID="grdTest" runat="server" />
</div>
</form>
</body>
</html>