23.2.3 高速缓存依赖性(2)

 

3. 创建定制的高速缓存依赖性

ASP.NET 2.0支持基于时间、基于文件和基于SQL的CacheDependency。那么,为什么还要编写定制的CacheDependency?其原因如下:

在Active Directory查询的结果中使高速缓存失效。

在MSMQ或MQSeries消息到来时使高速缓存失效。

创建专用于Oracle的CacheDependency。

使用XML Web服务报告的数据使高速缓存失效。

在Stock Price服务中用新数据更新高速缓存。

CacheDependency类的新版本没有对已有的ASP.NET 1.1代码做太大的修改,但增加了3个成员和一个构造函数重载。

GetUniqueID:重写时,可以给调用者返回定制的CacheDependency的唯一标识符。

DependencyDispose:用于释放定制的CacheDependency类使用的资源。在创建定制的CacheDependency时,需要实现这个方法。

NotifyDependencyChanged:根据定制的CacheDependency实例,使高速缓存过期。

新的公共构造函数。

程序清单23-4创建了一个新的RssCacheDependency,如果RSS(Rich Site Summary,丰富站点摘要) XML文档发生了变化,它就使高速缓存键失效。

程序清单23-4  创建RssCacheDependency类

VB
Imports System
Imports System.Web
Imports System.Threading
Imports System.Web.Caching
Imports System.Xml
Public Class RssCacheDependency
Inherits CacheDependency
    Shared backgroundThread As Timer
Dim howOften As Integer = 900
Dim RSS As XmlDocument
Dim RSSUrl As String
    Public Sub New(ByVal URL As String, ByVal polling As Integer)
howOften = polling
RSSUrl = URL
RSS = RetrieveRSS(RSSUrl)
        If backgroundThread Is Nothing Then
backgroundThread = New Timer( _
New TimerCallback(AddressOf CheckDependencyCallback), _
Me, (howOften * 1000), (howOften * 1000))
End If
End Sub
    Function RetrieveRSS(ByVal URL As String) As XmlDocument
Dim retVal As New XmlDocument
retVal.Load(URL)
Return retVal
End Function
    Public Sub CheckDependencyCallback(ByVal Sender As Object)
Dim CacheDepends As RssCacheDependency = _
CType(Sender, RssCacheDependency)
Dim NewRSS As XmlDocument = RetrieveRSS(RSSUrl)
If Not NewRSS.OuterXml = RSS.OuterXml Then
CacheDepends.NotifyDependencyChanged(CacheDepends, EventArgs.Empty)
End If
End Sub
    Protected Overrides Sub DependencyDispose()
backgroundThread = Nothing
MyBase.DependencyDispose()
End Sub
    Public ReadOnly Property Document() As XmlDocument
Get
Return RSS
End Get
End Property
End Class
C#
using System;
using System.Web;
using System.Threading;
using System.Web.Caching;
using System.Xml;
public class RssCacheDependency : CacheDependency
{
static Timer backgroundThread;
int howOften = 900;
XmlDocument RSS;
string RSSUrl;
    public RssCacheDependency(string URL, int polling)
{
howOften = polling;
RSSUrl = URL;
RSS = RetrieveRSS(RSSUrl);
        if (backgroundThread == null)
{
backgroundThread = new Timer(
new TimerCallback(CheckDependencyCallback),
this, (howOften * 1000), (howOften * 1000));
}
}
    public XmlDocument RetrieveRSS(string URL) 
{
XmlDocument retVal = new XmlDocument();
retVal.Load(URL);
return retVal;
}
    public void CheckDependencyCallback(object sender)
{
RssCacheDependency CacheDepends = sender as RssCacheDependency;
XmlDocument NewRSS = RetrieveRSS(RSSUrl);
if (NewRSS.OuterXml != RSS.OuterXml)
{
CacheDepends.NotifyDependencyChanged(CacheDepends, EventArgs.Empty);
}
}
    override protected void DependencyDispose()
{
backgroundThread = null;
base.DependencyDispose();
}
    public XmlDocument Document
{
get
{
return RSS;
}
}
}<%@ OutputCache Duration="90" VaryByParam="
pageId;subPageId" VaryByCustom="prefs"%>

创建一个新的Web站点,把RssCacheDependency类放在/Code文件夹中。创建default.aspx,在HTML设计视图中拖放两个文本框、一个标签和一个按钮。运行这个Web站点,输入blog的RSS URL(如www.hanselman.com/blog/SyndicationService.asmx/GetRss),单击按钮。程序就会把URL用作一个键,检查Cache对象。如果包含RSS的XmlDocument在高速缓存中不存在,就创建一个新的RssCacheDependency,其超时时间设置为10分钟(600秒)。然后高速缓存XmlDocument,以后的10分钟内对这个页面的请求都会从高速缓存中提取RSS XmlDocument。

程序清单23-4中新的RssCacheDependency类如下列代码所示。先创建RssCacheDependency,再把它传送给Cache.Insert调用。Cache对象处理生存期,并调用RssCacheDependency实例的方法:

VB
<%@ Page Language="VB" ValidateRequest="false" %>
<html>
<head runat="server">
<title>Custom Cache Dependency Example</title>
</head>
<body>
<form runat="server"> RSS URL:
<asp:TextBox ID="TextBox1" Runat="server"/>
<asp:Button ID="Button1" onclick="Button1_Click" Runat="server"
Text="Get RSS" />
Cached:<asp:Label ID="Label2" Runat="server"></asp:Label><br />
RSS:<br />
<asp:TextBox ID="TextBox2" Runat="server" TextMode="MultiLine"
Width="800px" Height="300px"></asp:TextBox>
</form>
</body>
</html>
<script runat="server">
Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim RSSUrl As String = TextBox1.Text
Label2.Text = "Loaded From Cache"
If Cache(TextBox1.Text) Is Nothing Then
Label2.Text = "Loaded Fresh"
Dim itDepends As New RssCacheDependency(RSSUrl, 600)
Cache.Insert(RSSUrl, itDepends.Document, itDepends)
End If
TextBox2.Text = CType(Cache(TextBox1.Text),_ _
System.Xml.XmlDocument).OuterXml
End Sub
</script>
C#
<%@ Page Language="C#" ValidateRequest="false" %>
<script runat="server">
void Button1_Click(object sender, System.EventArgs e)
{
string RSSUrl = TextBox1.Text;
Label2.Text = "Loaded From Cache";
if (Cache[TextBox1.Text] == null)
{
Label2.Text = "Loaded Fresh";
RssCacheDependency itDepends = new RssCacheDependency(RSSUrl, 600);
Cache.Insert(RSSUrl, itDepends.Document, itDepends);
}
TextBox2.Text = ((System.Xml.XmlDocument)Cache[TextBox1.Text]).OuterXml;
}
</script>

RssCacheDependency类创建一个Timer背景线程,检查RSS中的变化。如果RssCache Dependency检测到变化,就用NotifyDependencyChanged事件通知高速缓存子系统。清除高速缓存中带有该键的值,下一个页面视图必须从指定的地方重新加载请求的RSS。
posted @ 2008-12-29 19:06  李逍遥  阅读(316)  评论(0编辑  收藏  举报