程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> ASP.NET 2.0 中使用自定義緩存依賴

ASP.NET 2.0 中使用自定義緩存依賴

編輯:.NET實例教程

     在 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 寫一個自動刷新頁面的小功能,再把頁面美工一下,或是包裝成一個可復用的組件用在你的網站上,又或者只是想在本機裡做一個“我最關注的內容集”之類的東西?嗯,想來效果會比較不錯的哦。
  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved