ASP.NET缓存依赖--自定义缓存依赖
2012-04-08 22:09 马伟 阅读(910) 评论(0) 编辑 收藏 举报 在ASP.NET中,它允许你继承CacheDependency类创建自定义的缓存依赖,这和上一节所讲的SqlCacheDependency类所做的差不多。设计一个自定义的CacheDependency类很简单,你要做的只是启动一个异步任务,它检查依赖项目何时发生变化。依赖项目发生变化时,将调用基方法CacheDependency.NotifyDependencyChanged。作为回应,基类更新HasChanged与UTclastModified属性值,并且ASP.NET自动从缓存中移除所有相关项目。
我们知道,现在的许多网站都提供了RSS功能,从而方便我们去订阅。因此,在我们的应用程序里订阅这些RSS的时候,你可以在缓存中放置 RSS 数据,显示的时候使用一个样式转换。而在检查依赖性的时候,我们只需要简单地比较一下当前的 RSS 与网站的 RSS 是否相同就可以了。
那么我们该何时去检查比较这些RSS数据呢?其实,你可以使用一个 Timer 来控制,让它定期去检查一个是否有更新,如果有更新则通知依赖发生了改变。
此外为了便于重用,我们需要在自定义的缓存依赖类MyCacheDependency中定义一个url变量,用来保存我们要获取的 RSS 数据的 URL。还需要定义一个时间间隔timeInterval,便于在使用的时候调整刷新速度。详细代码如代码清单19-3所示:
代码清单19-3:MyCacheDependency.cs
using System.Collections.Generic;
using System.Xml.XPath;
using System.Web;
using System.Web.Caching;
using System.Threading;
namespace _19_1
{
public class MyCacheDependency : CacheDependency
{
private Timer _timer;
private int _timeInterval;
private XPathNavigator _rss;
private string _url;
private int _pollTime = 5000;
public XPathNavigator RSS
{
get
{
return _rss;
}
}
public MyCacheDependency(string url, int timeInterval)
{
_url = url;
_timeInterval = timeInterval;
_rss = GetRSS();
_timer = new Timer(
new TimerCallback(CheckDependencyCallback),
this, _timeInterval * _pollTime,
_timeInterval * _pollTime);
}
private XPathNavigator GetRSS()
{
XPathDocument doc = new XPathDocument(_url);
return doc.CreateNavigator();
}
public void CheckDependencyCallback(object sender)
{
XPathNavigator nav = GetRSS();
if (nav.OuterXml != _rss.OuterXml)
{
base.NotifyDependencyChanged(this,
EventArgs.Empty);
_timer.Dispose();
}
}
protected override void DependencyDispose()
{
if (_timer != null)
{
_timer.Dispose();
}
}
}
}
在MyCacheDependency类中,我们在CheckDependencyCallback方法里将两个 RSS 信息进行比较,如果不同,则调用 NotifyDependencyChanged 方法通知基类,相应的缓存依赖已经发生了变化,缓存中的数据应当被清除。
与此同时,在本类的最后还重写了DependencyDispose方法执行所有必需的清理工作。使用NotifyDependencyChanged方法使缓存的项目失效之后,很快就会调用DependencyDispose方法。此时,已经不再需要依赖了。
MyCacheDependency类的测试页面MyCacheDependencyWebForm.aspx 如代码清单19-4所示:
代码清单19-4:MyCacheDependencyWebForm.aspx
CodeBehind="MyCacheDependencyWebForm.aspx.cs"
Inherits="_19_1.MyCacheDependencyWebForm" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
博客园最新贴子:
<br />
<asp:Xml ID="RssXml" runat="server" />
<br />
<asp:Label ID="Label1" runat="server" ForeColor="red" />
</div>
</form>
</body>
</html>
在页面的后台代码里,我们首先需要判断RSS缓存项Cache["Key"]是否存在。如果Cache["Key"]为null,则调用MyCacheDependency类来创建一个缓存项,最后将缓存项绑定到RssXml控件上。如下面的代码所示:
{
protected void Page_Load(object sender, EventArgs e)
{
string url = "http://www.cnblogs.com/RSS.aspx";
if (Cache["Key"] == null)
{
MyCacheDependency dependency =
new MyCacheDependency(url, 500);
Cache.Insert("Key", dependency.RSS, dependency);
Label1.Text = "当前数据为刚刚获取,并已更新入缓存!";
}
else
{
Label1.Text = "当前数据系从缓存中取得!";
}
RssXml.XPathNavigator = Cache["Key"] as
System.Xml.XPath.XPathNavigator;
RssXml.TransformSource= "translate.xsl";
}
}
其中,translate.xsl文件代码如下所示:
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:myns="http://www.comesns.com/sample">
<xsl:template match="channel">
<div style="background-color:#cccccc; font-size :12px;">
<xsl:for-each select="item">
<a>
<xsl:attribute name="href">
<xsl:value-of select="link"/>
</xsl:attribute>
<xsl:value-of select="title"/>
</a>
<br />
</xsl:for-each>
</div>
</xsl:template>
</xsl:stylesheet>
因为在MyCacheDependencyWebForm页面中,我们给MyCacheDependency类传入的url是http://www.cnblogs.com/RSS.aspx。所以,示例运行结果如图所示: