ใน ASP.NET 1.x เราสามารถใช้ CacheDependency เพื่อใช้กลยุทธ์การพึ่งพาแคช แต่เนื่องจากคลาสนี้ถูกปิดผนึก เราจึงไม่สามารถสืบทอดคลาสนี้เพื่อใช้กลยุทธ์ของเราเองได้ แต่ด้วย ASP.NET 2.0 เราสามารถรับคลาสการพึ่งพาแคชของเราเองจากคลาสนี้ได้แล้ว
สมมติว่าเราต้องการออกแบบเพจและต้องการรับข้อมูลโพสต์ล่าสุดจากหน้าแรกของบล็อก เพื่อปรับปรุงประสิทธิภาพ เราหวังว่าข้อมูลเพจจะถูกสร้างขึ้นใหม่เมื่อมีการอัปเดตโฮมเพจของ Blog Park ไม่เช่นนั้นจะได้รับโดยตรงจากแคช จะบรรลุเป้าหมายได้อย่างไร?
1. ออกแบบคลาส BlogCacheDependency
และวิเคราะห์ก่อน ไม่ต้องสงสัยเลยว่าคลาสนี้ควรได้รับมาจาก CacheDependency จากนั้นจึงสามารถนำมาใช้ในวิธีการ Insert ของ Cache หรือใช้ในคลาส AggregateDependency
ประการที่สอง จากมุมมองของ RSS ที่ได้รับจาก Blog Park และการออกแบบเพจ คุณสามารถวางข้อมูล RSS ไว้ในแคชและใช้การแปลงรูปแบบเมื่อแสดงข้อมูลได้ เมื่อตรวจสอบการขึ้นต่อกัน เราเพียงแต่เปรียบเทียบว่า RSS ปัจจุบันเหมือนกับ RSS ของเว็บไซต์หรือไม่
คำถามที่สำคัญกว่านั้นคือ เราจะตรวจสอบและเปรียบเทียบข้อมูล RSS เมื่อใด ในทุกคำขอ? ไม่แน่นอน นี่เกือบจะเหมือนกับการไม่ใช้แคช และจริงๆ แล้วมันเป็นการเพิ่มภาระที่ไม่จำเป็น แล้วการเช็คอินโดยไม่ต้องร้องขอล่ะ? เราสามารถใช้ Timer เพื่อควบคุมและปล่อยให้มันตรวจสอบว่ามีการอัพเดตเป็นประจำหรือไม่ หากมีการอัพเดตก็จะแจ้งเตือนการขึ้นต่อกันของการเปลี่ยนแปลง
เรารู้ว่าคลาส CacheDependency มีคุณสมบัติ HasChanged แต่ BlogCacheDependency จะบอกคลาสพื้นฐานได้อย่างไรเมื่อตรวจพบการเปลี่ยนแปลงการพึ่งพา นี่คือภารกิจของเมธอด NotifyDependencyChanged ใหม่ในคลาส CacheDependency ใน ASP.NET 2.0
นอกจากนี้ เพื่อความสะดวกในการนำมาใช้ซ้ำ คลาส BlogCacheDependency ต้องมีข้อมูลฟีดเพื่อบันทึก URL ของข้อมูล RSS ที่เราต้องการได้รับ นอกจากนี้ยังมีช่วงเวลาอำนวยความสะดวกในการปรับความเร็วรีเฟรชระหว่างการใช้งาน
ตกลง มาดูโค้ดการใช้งานจริงกันดีกว่า:
1public class BlogCacheDependency : CacheDependency
2{
3 ตัวจับเวลาส่วนตัว _tickTimer;
4 ส่วนตัว int _timeInterval;
5 XPathNavigator ส่วนตัว _rss;
6 สตริงส่วนตัว _feed;
7
8 XPathNavigator RSS สาธารณะ
9 {
10 ได้รับ
11 {
12 กลับ _rss;
13}
14}
15
16 BlogCacheDependency สาธารณะ (ฟีดสตริง, int timeInterval)
17 {
18 _ฟีด = ฟีด;
19 _timeInterval = ช่วงเวลา;
20 _rss = GetRSS();
21 _tickTimer = ตัวจับเวลาใหม่ (TimerCallback ใหม่ (CheckDependencyCallback)
22 นี้, _timeInterval * 1,000, _timeInterval * 1,000);
ยี่สิบสาม }
ยี่สิบสี่
25 XPathNavigator ส่วนตัว GetRSS()
26 {
27 XPathDocument rssDoc = XPathDocument ใหม่(_feed);
28 กลับ rssDoc.CreateNavigator();
29 }
30
31 โมฆะสาธารณะ CheckDependencyCallback (ผู้ส่งวัตถุ)
32 {
33 BlogCacheDependency bcd = ผู้ส่งเป็น BlogCacheDependency;
34 XPathNavigator ใหม่RSS = GetRSS();
35 ถ้า (newRSS.OuterXml != _rss.OuterXml)
36 {
37 bcd.NotifyDependencyChanged(bcd, EventArgs.Empty);
38 }
39 }
40
41 การแทนที่การป้องกันเป็นโมฆะ DependencyDispose ()
42 {
43 _tickTimer = โมฆะ;
44 ฐาน DependencyDispose();
45 }
46}
47
48
ที่นี่ ตัวสร้างของ BlogCacheDependency ใช้ _tickTimer เพื่อใช้กลไกสำหรับการตรวจสอบการอัปเดตเป็นประจำ ซึ่งเรียกเมธอด CheckDependencyCallback ตามช่วงเวลาที่กำหนด
วิธีการ CheckDependencyCallback จะเปรียบเทียบข้อมูล RSS ทั้งสอง หากแตกต่างกัน วิธีการ NotifyDependencyChanged จะถูกเรียกเพื่อแจ้งคลาสพื้นฐานว่ามีการเปลี่ยนแปลงการขึ้นต่อกันของแคช และข้อมูลในแคชควรถูกล้าง
2. การออกแบบหน้า
ต่อไปนี้เป็นโค้ดของหน้า (ย่อ) ซึ่งแสดงวิธีใช้ BlogCacheDependency:
1<script runat="server">
2 โมฆะที่ได้รับการป้องกัน Page_Load (ผู้ส่งวัตถุ EventArgs e)
3 {
ฟีด 4 สาย = " http://www.cnblogs.com/RSS.aspx ";
5 ถ้า (แคช [ฟีด] == null)
6 {
7 BlogCacheDependency bcd = BlogCacheDependency ใหม่ (ฟีด, 600);
8 แคชแทรก (ฟีด, bcd.RSS, bcd);
9 Label1.Text = "ข้อมูลปัจจุบันเพิ่งได้รับและอัปเดตลงในแคชแล้ว!";
10}
11 อื่น ๆ
12 {
13 Label1.Text = "ข้อมูลปัจจุบันได้มาจากแคช!";
14}
15 RssXml.XPathNavigator = แคช [ฟีด] เป็น System.Xml.XPath.XPathNavigator;
16 RssXml.TransformSource = "translate.xsl";
17}
18</สคริปต์>
19
20<ร่างกาย>
21 <form id="form1" runat="server">
22 บล็อกพาร์ค โพสต์ล่าสุด:
23 <br />
24 <asp:Xml ID="RssXml" runat="เซิร์ฟเวอร์" />
25 <br />
26 <asp:Label ID="Label1" runat="server" ForeColor="สีแดง" />
27 </แบบฟอร์ม>
28</ร่างกาย>
29
ในตัวอย่างนี้ ช่วงเวลาที่ตั้งค่าสำหรับการเข้าถึงรายการโพสต์ล่าสุดบนหน้าแรกของ Blog Park คือ 600 วินาที นั่นคือ สถานะการอัปเดตจะถูกตรวจสอบทุกๆ 10 นาที
ประเด็นที่น่าสังเกตหลายประการ:
1. ให้ความสนใจกับแอตทริบิวต์ RssXml.XPathNavigator ที่ใช้ บางคนอาจสงสัยว่าเหตุใดจึงไม่ใช้ RssXml.Document ที่จริงแล้ว แอตทริบิวต์ Document ถูกยกเลิกใน .NET 2.0 การแทนที่ที่แนะนำคือแอตทริบิวต์ XPathNavigator ดังที่คุณเห็นจากคลาส BlogCacheDependency ก่อนหน้านี้ มันถูกสร้างขึ้นจาก XPathDocument.CreateNavigator() คลาส XPathDocument มีแคชแบบอ่านอย่างเดียวที่รวดเร็ว ซึ่งเห็นได้ชัดว่าเหมาะสมกว่าสำหรับตัวอย่างนี้
2. ลองคิดดู จุดประสงค์ของเมธอด DependencyDispose ในคลาส BlogCacheDependency คืออะไร แตกต่างจากวิธี Dispose อย่างไร? ลองคิดดู หากพบการเปลี่ยนแปลงการพึ่งพาเมื่อตรวจสอบการอัปเดต แต่ไม่ได้ส่งคำขออีกครั้ง วิธีการ CheckDependencyCallback จะถูกดำเนินการอย่างต่อเนื่องตามช่วงเวลาหรือไม่ หากเป็นกรณีนี้จริง ๆ มันจะไม่ซ้ำซ้อนโดยสิ้นเชิง เพราะตราบใดที่ตรวจพบการเปลี่ยนแปลงเพียงครั้งเดียว ก็ไม่จำเป็นต้องตรวจสอบอีกครั้ง และหากเราติดตามหรือบันทึกบันทึก เราจะพบว่าในความเป็นจริง ตราบใดที่พบการเปลี่ยนแปลงการขึ้นต่อกัน ก็จะไม่ได้รับการตรวจสอบอีกครั้ง ความลับคืออะไร? ถ้าคุณลองคิดดู คุณจะรู้ว่าเมธอด NotifyDependencyChanged มีความลึกลับมากมาย และเหตุผลที่ว่าทำไมเมธอด DependencyDispose ก็อยู่ที่นี่จริงๆ แนวคิดการออกแบบในนั้นคุ้มค่าแก่การลิ้มลอง
3. ฉันจะไม่พูดอะไรเพิ่มเติมเกี่ยวกับ Translate.xsl ที่ใช้ในเพจ
แต่นี่คือโค้ดหลัก:
1<xsl:template match="channel">
2 <ดิวิชั่น>
3 <xsl:for-each select="item">
4 <ก>
5 <xsl:ชื่อแอตทริบิวต์="href">
6 <xsl:value-of select="link"/>
7 </xsl:แอตทริบิวต์>
8 <xsl:value-of select="title"/>
9 </a>
10 <br />
11 </xsl:สำหรับแต่ละ>
12 </div>
13</xsl:แม่แบบ>
4. การดำเนินการ:
นี่เป็นภาพหน้าจอของการดำเนินการครั้งแรก:
เมื่อไม่มีโพสต์ใหม่ปรากฏบนหน้าแรกของสวนบล็อก เราจะรีเฟรชหน้านี้และรับหน้าต่อไปนี้เสมอ:
เมื่อมีการโพสต์ใหม่ รูปภาพก่อนหน้า จะปรากฏขึ้นเมื่อทำการรีเฟรช
5. คุณต้องการที่จะก้าวหน้ากว่านี้หรือไม่?
หากคุณขี้เกียจเหมือนฉันหรือขี้เกียจกว่าฉัน คุณสามารถลองใช้ javascript เพื่อเขียนฟังก์ชันเล็กๆ ที่จะรีเฟรชเพจโดยอัตโนมัติ จากนั้นจึงตกแต่งเพจหรือรวมแพ็คเกจเป็นส่วนประกอบที่นำมาใช้ซ้ำได้เพื่อใช้บนเว็บไซต์ของคุณ หรือคุณ แค่ต้องการสร้างบางอย่างเช่น "คอลเลกชันเนื้อหาที่ฉันสนใจมากที่สุด" ในเครื่องนี้ ฉันคิดว่าเอฟเฟกต์จะค่อนข้างดี