ASP.NET:性能与缓存[续]

《ASP.NET系列讲座之一:性能与缓存》讲座还提到了通过缓存的设置来提高ASP.NET的性能。设置缓冲的方法是: 

<%@OutputCache%> 


它主要有两个参数:DurationVaryByParam


Duration:设置页面或控件进行缓存的时间(单位:秒)。例如我要设置缓存为60秒内有效,我就可以这样设置:

<%@ OutputCache Duration=60“ VaryByParam=“none“ %>


设置Cache有什么好处呢?举个简单的例子,你想通过网页查询某些数据,而这些数据并非实时变化,或者变化的时间是有期限的,例如查询气温。我们没有必要了解每秒每刻的气温,只需要知道当天的气温就OK了。那么我在午时一点钟和在一点过一分钟的时候去查询的气温应该完全一致。如果不设置缓存,哪怕你查询的数据完全一致,ASP.NET也会根据你的需要重复查询两次,这就增加了不必要的开销。

如果设置了缓存,只要没有过Duration所设置的期限,那么ASP.NET就直接在缓存里查询即可。

通过ACT(Application Center Test)的测试,发现设置缓存后执行的性能比未设置缓存时的性能足足提高了三倍多。


可能大家已经看到了在上面的代码中,我们将”VaryByParam“设置为none,这个参数又有什么用了。还是举刚才那个例子。我们通过城市名来查询当地的气温。例如输入“beijing”,获得的气温是27。获得的值会放入到缓存中。然而我们在60秒内,接着输入“shanghai”,因为设置缓存的原因,获取的并非shanghai的气温,而是之前放入到缓存中的beijing的气温27。

解决的办法就是使用VaryByParam。通过它可以根据设置的参数值建立不同的缓存。如果我们输入的城市名是在一个TextBox中,且该控件的ID为”txtCity”,那么我们可以将其设置到VaryByParam中:

<%@ OutputCache Duration=60” VaryByParam=”txtCity” %>

此时,当我们输入“beijing”时,存储到缓存的是beijing的值。如果再60秒内输入其它城市,例如“shanghai”,它会在缓存中查询是否有参数值为“shanghai”的缓存值,如果没有去重新获得,否则读出相应的值。这样就可以避免上面所说的错误结果。

上面所述的缓冲实际上是页面缓冲,也就是说,这个缓冲是针对整个页面而言的。在ASP.NET中还有一种称为“片断缓冲”。缓冲的作用域是在UserControl中。

在ASP.NET中,提供了UserControl这种用户控件的功能。一个页面可以通过多个UserControl来组成。如果只需要在某个或某几个UserControl里设置缓存。那么可以在UserControl的Html代码中添加语句:

<%@ OutputCache Duration=60“ % 〉

 

当然在UserControl中也仍然存在缓存值重复的问题。这个时候可以使用VaryByControl参数来进行设置。这个设置相当于将缓存按照UserControl进行分区。方法与设置VaryByParam相似。

posted on 2004-10-01 18:28 张逸 阅读(1703) 评论(6)  编辑 收藏 所属分类: ASP.NET

评论

#1楼  2004-10-01 19:25 dudu      

推荐一篇对“片断缓冲”分析得比较透彻的文章:
http://weblogs.asp.net/dmarsh/archive/2003/11/26/39793.aspx
“片断缓冲”英文是PartialCaching, 我一直把它翻译成“局部缓存”。   回复  引用  查看    

#2楼  2004-10-02 18:54 unruledboy(灵感之源)      

疑惑:既然是根据控件内容,那么:
1、如果我要根据多个控件改变才刷新呢?;
2、.NET必须先取内容(执行代码)要知道是否改变,这意味着无论页面怎样,无论缓冲间隔怎样,都必须执行。这意味着什么呢?其实每次请求都要执行页面,那到底这个Output Cache的意义何在?   回复  引用  查看    

#3楼 [楼主] 2004-10-02 19:35 wayfarer      

@灵感之源

1、如果是多个控件,可以在VaryByParam的设置中设置多个控件的ID,中间以“,”隔开。

2、两者执行的内容不一样。例如我要缓存的是根据textBox的值所获取的结果。且这个结果需要进行大量的运算,或者需要访问数据库后才能获得。那么首先执行的仅仅是获得textBox的值而已,然后才会执行下面的执行代码。

如果没有缓存,ASP.NET会每次都进行运算。如果设置了缓存,ASP.NET需要做的工作只是首先获得textBox的值,然后去查询缓存,如果缓存里存在了该结果,就省去了大量运算的时间。这极大地提高了性能。

当然,设置缓存并非必须的。如果你要获得的结果是实时变化的,设置了缓存反而会降低性能。因此,是否设置缓存,要根据具体的情况而定。
  回复  引用  查看    

#4楼  2004-10-02 23:04 unruledboy(灵感之源)      

你还是没有理解:

譬如txtCity,肯定是通过代码“绑定”内容,对吗?那意味着肯定执行代码才知道,对吗?那意味着每次都要执行才知道是否有改变,对吗?那这个缓冲到底有什么用?   回复  引用  查看    

#5楼 [楼主] 2004-10-03 11:23 wayfarer      

呵呵.其实我是明白你的意思的了,可能是我描述不太清楚。

还是举这个例子,一个txtCity,另外还有个Button,为Request。这两个控件都是服务器控件。相应Button_Click事件后,会执行一段代码。代码会根据txtCity的text值,去取相应的值。

如果不设置缓冲的话,当我们单击Button时,会执行这段Button_Click的代码。然而一旦设置了缓冲,ASP.NET会先判断<%@ OutPut %>语句,并根据VaryByParam里设置的控件ID,先获取该控件改变的值,这里由于绑定的是txtCity,因此会先获取txtCity.Text值(因为txtCity是服务器控件,他的ViewState是否改变,即它的值是否改变,改变后的值是多少,服务器是可以获得的)。然后根据该值去查询缓冲(当然在之前事实上会先判断Duration设置的时间是否过期),如果缓冲已有相应的值,则直接从缓冲里获取即可,就不用再执行Button_Click中根据text获取值的代码了。

虽然这个过程很复杂,看起来也很麻烦,但如果这个运算非常耗时间的话,设置缓冲就是很有价值的。至于ASP.NET如何来设置缓冲,怎样去判断哪些代码执行,哪些代码不执行,我就不太清楚了:)   回复  引用  查看    

#6楼  2004-10-08 23:27 caca      

缓存应该注意一个问题:
在缓存时间内,页面的Button不能触发事件
(比如,登陆框的"提交"按钮无效)   回复  引用  查看    


标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2004-10-01 18:48 编辑过
"五向定位"职业成长路线公开课(上海、南京、大连)
Google站内搜索


相关链接:
 



导航

公告

logo.gif
我的著作与译作

《软件设计精要与模式》

《WCF服务编程》

MVP_Horizontal_BlueOnly.png

From 03-03-2006
Counter: site stats

与我联系

搜索

 

常用链接

我参加的小组

我参与的团队

随笔分类(245)

随笔档案(237)

最新随笔

积分与排名

最新评论

阅读排行榜

评论排行榜