In ASP.NET 1.x können wir CacheDependency verwenden, um Cache-Abhängigkeitsstrategien zu implementieren. Da diese Klasse jedoch versiegelt ist, können wir diese Klasse nicht erben, um unsere eigenen Strategien zu implementieren. Aber mit ASP.NET 2.0 können wir bereits unsere eigenen Cache-Abhängigkeitsklassen von dieser Klasse ableiten.
Angenommen, wir möchten eine Seite entwerfen und müssen die neuesten Beitragsinformationen von der Blog-Homepage abrufen. Um die Leistung zu verbessern, hoffen wir, dass die Seitendaten nur dann neu generiert werden, wenn die Homepage des Blogparks aktualisiert wird, andernfalls werden sie direkt aus dem Cache abgerufen. Wie erreicht man es?
1. Entwerfen Sie zunächst die BlogCacheDependency-Klasse
und analysieren Sie sie. Zunächst besteht kein Zweifel daran, dass diese Klasse von CacheDependency abgeleitet werden sollte. Anschließend kann sie in der Insert-Methode von Cache oder in der AggregateDependency-Klasse verwendet werden.
Zweitens können Sie aus der Perspektive des von Blog Park bereitgestellten RSS und des Seitendesigns RSS-Daten im Cache platzieren und bei der Anzeige eine Stilkonvertierung verwenden. Bei der Prüfung der Abhängigkeiten müssen wir lediglich vergleichen, ob der aktuelle RSS mit dem RSS der Website übereinstimmt.
Eine wichtigere Frage ist: Wann prüfen und vergleichen wir RSS-Daten? Auf jede Anfrage? Offensichtlich nicht. Dies ist fast dasselbe, als würde man den Cache nicht verwenden, und es stellt tatsächlich eine unnötige Belastung dar. Wie wäre es mit einem unaufgeforderten Check-in? Wir können einen Timer verwenden, um es zu steuern und regelmäßig prüfen zu lassen, ob ein Update vorliegt. Wenn es ein Update gibt, wird die Abhängigkeit über die Änderung benachrichtigt.
Wir wissen, dass die CacheDependency-Klasse eine HasChanged-Eigenschaft hat, aber wie teilt BlogCacheDependency ihrer Basisklasse mit, wenn sie eine Abhängigkeitsänderung erkennt? Dies ist die Aufgabe der neuen NotifyDependencyChanged-Methode in der CacheDependency-Klasse in ASP.NET 2.0.
Um die Wiederverwendung zu erleichtern, muss die BlogCacheDependency-Klasse außerdem über Feeddaten verfügen, um die URL der RSS-Daten zu speichern, die wir erhalten möchten. Es gibt auch ein Zeitintervall, um die Anpassung der Aktualisierungsgeschwindigkeit während der Nutzung zu erleichtern.
OK, werfen wir einen Blick auf den tatsächlichen Implementierungscode:
1public class BlogCacheDependency: CacheDependency
2{
3 privater Timer _tickTimer;
4 private int _timeInterval;
5 privater XPathNavigator _rss;
6 private Zeichenfolge _feed;
7
8 öffentliches XPathNavigator-RSS
9 {
10 bekommen
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);
dreiundzwanzig }
vierundzwanzig
25 privater 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
Hier implementiert der Konstruktor von BlogCacheDependency mit _tickTimer einen Mechanismus zur regelmäßigen Überprüfung von Updates, der die CheckDependencyCallback-Methode entsprechend dem eingestellten Zeitintervall aufruft.
Die CheckDependencyCallback-Methode vergleicht die beiden RSS-Informationen. Wenn sie unterschiedlich sind, wird die NotifyDependencyChanged-Methode aufgerufen, um die Basisklasse darüber zu informieren, dass sich die entsprechende Cache-Abhängigkeit geändert hat und die Daten im Cache gelöscht werden sollten.
2. Seitendesign
Das Folgende ist der Seitencode (gekürzt), der zeigt, wie BlogCacheDependency verwendet wird:
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 = "Die aktuellen Daten wurden gerade abgerufen und im Cache aktualisiert!";
10}
11 sonst
12 {
13 Label1.Text = "Die aktuellen Daten werden aus dem Cache bezogen!";
14}
15 RssXml.XPathNavigator = Cache[feed] als System.Xml.XPath.XPathNavigator;
16 RssXml.TransformSource = "translate.xsl";
17}
18</script>
19
20<Körper>
21 <form id="form1" runat="server">
22 neueste Blog Park-Beiträge:
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
In diesem Beispiel beträgt das eingestellte Zeitintervall für den Zugriff auf die Liste der neuesten Beiträge auf der Homepage des Blogparks 600 Sekunden, d. h. der Aktualisierungsstatus wird alle 10 Minuten überprüft.
Einige erwähnenswerte Punkte:
1. Achten Sie auf das verwendete RssXml.XPathNavigator-Attribut. Manche Leute fragen sich vielleicht, warum RssXml.Document nicht verwendet wird. Tatsächlich wurde das Document-Attribut in .NET 2.0 abgeschafft. Der empfohlene Ersatz ist das XPathNavigator-Attribut. Wie Sie der vorherigen BlogCacheDependency-Klasse entnehmen können, können wir das aus MSDN erkennen. Die XPathDocument-Klasse stellt einen schreibgeschützten schnellen Cache bereit, der für dieses Beispiel offensichtlich besser geeignet ist.
2. Denken Sie darüber nach: Was ist der Zweck der DependencyDispose-Methode in der BlogCacheDependency-Klasse? Wie unterscheidet es sich von der Dispose-Methode? Lassen Sie uns darüber nachdenken, ob bei der Suche nach Updates eine Abhängigkeitsänderung festgestellt wurde, die Anfrage jedoch nicht erneut gesendet wurde. Wird die CheckDependencyCallback-Methode dann kontinuierlich in Abständen ausgeführt? Wenn dies wirklich der Fall ist, wäre das dann nicht völlig überflüssig, denn solange eine Änderung einmal erkannt wird, ist keine erneute Überprüfung erforderlich. Und wenn wir Protokolle verfolgen oder aufzeichnen, können wir feststellen, dass Abhängigkeitsänderungen tatsächlich nicht erneut überprüft werden, solange sie gefunden werden. Was ist das Geheimnis? Wenn Sie darüber nachdenken, werden Sie wissen, dass die NotifyDependencyChanged-Methode viele Geheimnisse birgt und der Grund, warum es eine DependencyDispose-Methode gibt, tatsächlich hier liegt. Die darin enthaltenen Designideen sind einen Besuch wert.
3. Ich werde nicht mehr über die auf der Seite verwendete Translate.xsl sagen
, aber hier sind die Hauptcodes:
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>
4. Ausführung:
Dies ist ein Screenshot der ersten Ausführung:
Wenn auf der Startseite des Bloggartens keine neuen Beiträge erscheinen, aktualisieren wir die Seite und erhalten immer die folgende Seite:
Sobald es einen neuen Beitrag gibt, erscheint beim Aktualisieren das vorherige Bild.
5. Möchten Sie fortgeschrittener werden?
Wenn Sie genauso faul sind wie ich oder noch fauler als ich, können Sie erwägen, mit Javascript eine kleine Funktion zu schreiben, die die Seite automatisch aktualisiert, und dann die Seite zu dekorieren oder sie in eine wiederverwendbare Komponente zur Verwendung auf Ihrer Website zu packen. Oder Sie tun es Möchten Sie auf dieser Maschine einfach so etwas wie eine „Inhaltssammlung, die mir am meisten am Herzen liegt“ erstellen? Nun, ich denke, der Effekt wird ziemlich gut sein.