分享
 
 
 

ASP.NET 2.0 中使用自定义缓存依赖

王朝asp·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

在 asp.net 1.x 中,我们可以使用 CacheDependency 来实现缓存依赖策略,但由于这个类是 sealed 的,我们无法继承这个类来实现我们自己的策略。但是到了 ASP.NET 2.0,我们已经可以从这个类派生出自己的缓存依赖类了。

假定我们要设计一个页面,需要从博客园首页获取最新的贴子信息。为了提高性能,我们希望页面数据仅当博客园首页有更新时才重新生成,否则的话就直接从缓存中获取。如何实现?

一、设计 BlogCacheDependency 类

先分析一下,首先,毫无疑问的,这个类应当从 CacheDependency 派生出来,然后它才能在 Cache 的 Insert 方法中使用,或者被用在 AggregateDependency 类中。

其次,从博客园提供的 rss 以及页面设计的角度考虑,可以在缓存中放置 RSS 数据,显示的时候使用一个样式转换。而在检查依赖性的时候,我们只需要简单地比较一下当前的 RSS 与网站的 RSS 是否相同就可以了。

一个比较重要的问题是:我们何时去检查比较 RSS 数据?在每次请求的时候吗?显然不行,这样一来跟不使用缓存几乎没什么区别,甚至实际上加重了无谓的负担。考虑在没有请求的时候进行检查呢?我们可以使用一个 Timer 来控制,让它定期去检查一个是否有更新,如果有更新则通知依赖发生了改变。

我们知道 CacheDependency 类有一个 HasChanged 属性,但是当 BlogCacheDependency 检查到依赖改变时如何告诉它的基类呢?这就是在 ASP.NET 2.0 中 CacheDependency 类中新增的 NotifyDependencyChanged 方法的使命了。

此外为了便于重用,BlogCacheDependency 类须得有一个 feed 数据,用来保存我们要获取的 RSS 数据的 URL。还要有一个时间间隔,便于在使用的时候调整刷新速度。

好,看看实际的实现代码:

1public class BlogCacheDependency : CacheDependency

2{

3 PRivate Timer _tickTimer;

4 private int _timeInterval;

5 private XPathNavigator _rss;

6 private string _feed;

7

8 public XPathNavigator RSS

9 {

10 get

11 {

12 return _rss;

13 }

14 }

15

16 public BlogCacheDependency(string feed, int timeInterval)

17 {

18 _feed = feed;

19 _timeInterval = timeInterval;

20 _rss = GetRSS();

21 _tickTimer = new Timer(new TimerCallback(CheckDependencyCallback),

22 this, _timeInterval * 1000, _timeInterval * 1000);

23 }

24

25 private XPathNavigator GetRSS()

26 {

27 XPathDocument rssDoc = new XPathDocument(_feed);

28 return rssDoc.CreateNavigator();

29 }

30

31 public void CheckDependencyCallback(object sender)

32 {

33 BlogCacheDependency bcd = sender as BlogCacheDependency;

34 XPathNavigator newRSS = GetRSS();

35 if (newRSS.Outerxml != _rss.OuterXml)

36 {

37 bcd.NotifyDependencyChanged(bcd, EventArgs.Empty);

38 }

39 }

40

41 protected override void DependencyDispose()

42 {

43 _tickTimer = null;

44 base.DependencyDispose();

45 }

46}

47

48

这里,BlogCacheDependency 的构造函数中使用 _tickTimer 实现了一个定时检查更新的机制,它根据设定的时间间隔去调用 CheckDependencyCallback 方法。

而 CheckDependencyCallback 方法则将两个 RSS 信息进行比较,如果不同,则调用 NotifyDependencyChanged 方法通知基类,相应的缓存依赖已经发生了变化,缓存中的数据应当被清除。

二、页面设计

下面是页面代码(有删节),其中显示了 BlogCacheDependency 的使用方法:

1<script runat="server">

2 protected void Page_Load(object sender, EventArgs e)

3 {

4 string feed = "http://www.cnblogs.com/RSS.aspx";

5 if (Cache[feed] == null)

6 {

7 BlogCacheDependency bcd = new BlogCacheDependency(feed, 600);

8 Cache.Insert(feed, bcd.RSS, bcd);

9 Label1.Text = "当前数据为刚刚获取,并已更新入缓存!";

10 }

11 else

12 {

13 Label1.Text = "当前数据系从缓存中取得!";

14 }

15 RssXml.XPathNavigator = Cache[feed] as System.Xml.XPath.XPathNavigator;

16 RssXml.TransformSource = "translate.xsl";

17 }

18</script>

19

20<body>

21 <form id="form1" runat="server">

22 博客园最新贴子:

23 <br />

24 <asp:Xml ID="RssXml" runat="server" />

25 <br />

26 <asp:Label ID="Label1" runat="server" ForeColor="red" />

27 </form>

28</body>

29

本例中设定的访问博客园首页最新贴子列表,时间间隔为600秒,即每10分钟检查一次更新情况。

几个值得注意的地方:

1、注意使用的 RssXml.XPathNavigator 属性,有人可能奇怪为什么不用 RssXml.Document 呢?实际上 Document 属性在 .NET 2.0 中已废除,推荐用来替代的是 XPathNavigator 属性,从前面的 BlogCacheDependency 类中可以看到,它是来源于 XPathDocument.CreateNavigator() 所创建的,从 MSDN 我们可以知道,XPathDocument 类提供一种只读的快速缓存,显然就这个例子而言确实更加适合。

2、考虑一下,BlogCacheDependency 类中的 DependencyDispose 方法作何用?它与 Dispose 方法有何区别?让我们想一想,如果说某一次检查更新时,已经发现依赖变化了,但是却一直没有再次发送请求,那么这时会不会始终连续不断按间隔地执行 CheckDependencyCallback 方法呢?如果真的如此的话,那岂不是完全多余,因为只要查到一次有变化就不必再查了嘛。而如果我们进行跟踪或是记录日志的话可以发现,实际上只要查到依赖变化以后就不会再次 Check 了。奥妙在哪里?想一想就能知道 NotifyDependencyChanged 方法大有玄机,而且之所以会有 DependencyDispose 方法的原因其实也就在这里。其中的设计思想,值得我们细细品味吧。

三、页面使用到的 translate.xsl

不再多说,贴出主要代码:

1<xsl:template match="channel">

2 <div>

3 <xsl:for-each select="item">

4 <a>

5 <xsl:attribute name="href">

6 <xsl:value-of select="link"/>

7 </xsl:attribute>

8 <xsl:value-of select="title"/>

9 </a>

10 <br />

11 </xsl:for-each>

12 </div>

13</xsl:template>

四、执行情况

这是最初执行的截图:

当博客园首页没有出现新贴子的时候,我们刷新页面,总是可以得到如下的页面:

而一旦有了新贴子,那么刷新的时候出现的是上一张图。

五、你想再高级一点吗?

如果你和我一样懒或是比我更懒,那么你可以考虑再用 javascript 写一个自动刷新页面的小功能,再把页面美工一下,或是包装成一个可复用的组件用在你的网站上,又或者只是想在本机里做一个“我最关注的内容集”之类的东西?嗯,想来效果会比较不错的哦。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有