如何:从缓存中移除项时通知应用程序
在大多数缓存方案中,当从缓存中移除项后,直到再次需要此项时,才需要将其放回缓存中。典型的开发模式是在使用项之前始终检查该项是否已在缓存中。如果项位于缓存中,则可以使用。如果不在缓存中,则应再次检索该项,然后将其添加回缓存。
但是,在某些情况下,如果从缓存中移除项时通知应用程序,可能非常有用。例如,您可能具有一个缓存的报告,创建该报告需花费大量的时间进行处理。当该报告从缓存中移除时,您希望重新生成该报告,并立即将其置于缓存中,以便下次请求该报告时,用户不必等待对此报告进行处理。
为了在从缓存中移除项时能够发出通知,ASP.NET 提供了 CacheItemRemovedCallback 委托。该委托定义编写事件处理程序时使用的签名,当对从缓存中移除项进行响应时会调用此事件处理程序。ASP.NET 还提供 CacheItemRemovedReason 枚举,用于指定移除缓存项的原因。
通常,通过在管理尝试检索的特定缓存数据的业务对象中创建处理程序,来实现回调。例如,您可能有一个 ReportManager 对象,该对象具有两种方法,即 GetReport 和 CacheReport。GetReport 报告方法检查缓存以查看报告是否已缓存;如果没有,该方法将重新生成报告并将其缓存。CacheReport 方法具有与 CacheItemRemovedCallback 委托相同的函数签名;从缓存中移除报告时,ASP.NET 会调用 CacheReport 方法,然后将报告重新添加到缓存中。
当从缓存中移除项时通知应用程序
-
创建一个类,负责从缓存中检索项并处理回调方法,以将项添加回缓存中。
-
在该类中,创建用于将项添加到缓存中的方法。
-
在该类中,创建用于从缓存中获取项的方法。
-
创建用于处理缓存项移除回调的方法。该方法必须具备与 CacheItemRemovedCallback 委托相同的函数签名。从缓存中删除项时,会在该方法中执行要运行的逻辑,如重新生成项并将其添加回缓存中。
测试缓存项回调
-
创建一个 ASP.NET 网页,该网页将调用类中用于将项添加到缓存中的方法。
下面的代码示例演示如何调用 ReportManager 类的 GetReport 方法(在此过程后面的示例中定义)。然后将在使用页面的 Page_Load 方法期间显示 Label 控件 Label1 中的报告。
protected void Page_Load(object sender, EventArgs e)
{
this.Label1.Text = ReportManager.GetReport();
}
2.在浏览器中请求 ASP.NET 页并查看报告。 报告是在首次请求页时创建的,在缓存中的报告被移除之前,后续请求都将访问缓存中的报告。
示例
下面的代码示例演示一个名为 ReportManager 的、用于在从缓存中删除项时处理通知的完整类。该类管理字符串形式的报告,此报告表示一个长期运行的进程。
尽管该示例使用声明为 static(在 Visual Basic 中为 Shared)的类,但并不是必须使用静态类。不过,删除缓存项时,用于处理回调的方法必须存在。例如,不应在 ASP.NET 页中实现回调处理程序,因为在从缓存中删除项之前该页可能已被释放,因此用于处理回调的方法将不可用。为了确保从缓存中删除项时处理回调的方法仍然存在,请使用该方法的静态类。但是,静态类的缺点是需要保证所有静态方法都是线程安全的。
警告 |
|---|
|
请不要在页面中将 CacheItemRemovedCallback 设置为一个方法。除了在释放页面后回调无法使用页面方法以外,将回调指向页面方法还会阻碍垃圾回收将页面使用的内存回收。由于回调包含对页面的引用,而垃圾回收器不会从内存中移除包含任何引用的项,因此会出现这种情况。在加载应用程序期间,这可能会导致内存很快被用光。 |
该示例类包括以下功能:
-
私有成员,用于跟踪报告是否已从缓存中移除。
-
名为 CacheReport 的方法,用于将项以 MyReport 的名称添加到缓存中,并将该项设置为在添加到缓存中后一分钟过期。该方法还会将 ReportRemovedCallback 方法传递给 onRemoveCallback 参数,从而注册 ReportRemoveCallback 方法,以便在从缓存中删除项时进行调用。
-
名为 GetReport 的方法,用于从缓存中获取项。该方法确定名为 MyReport 的项是否存在于缓存中。如果该项不存在,则该方法将调用 CacheReport,,将该项添加到缓存中。
-
名为 ReportRemovedCallback 的方法,用于处理缓存项移除回调。ReportRemovedCallback 具有与 CacheItemRemovedCallback 委托相同的函数签名。该方法将变量 _reportRemovedFromCache 设置为 true,然后通过 CacheReport 方法将项添加回缓存中。
using System;
using System.Web;
using System.Web.Caching;
public static class ReportManager
{
private static bool _reportRemovedFromCache = false;
static ReportManager()
{ }
public static String GetReport()
{
lock (typeof(ReportManager))
{
if (HttpContext.Current.Cache["MyReport"] != null)
return (string)HttpRuntime.Cache["MyReport"];
else
{
CacheReport();
return (string)HttpRuntime.Cache["MyReport"];
}
}
}
public static void CacheReport()
{
lock (typeof(ReportManager))
{
HttpContext.Current.Cache.Add("MyReport",
CreateReport(), null, DateTime.MaxValue,
new TimeSpan(0, 1, 0),
System.Web.Caching.CacheItemPriority.Default,
ReportRemovedCallback);
}
}
private static string CreateReport()
{
System.Text.StringBuilder myReport =
new System.Text.StringBuilder();
myReport.Append("Sales Report<br />");
myReport.Append("2005 Q2 Figures<br />");
myReport.Append("Sales NE Region - $2 million<br />");
myReport.Append("Sales NW Region - $4.5 million<br />");
myReport.Append("Report Generated: " + DateTime.Now.ToString()
+ "<br />");
myReport.Append("Report Removed From Cache: " +
_reportRemovedFromCache.ToString());
return myReport.ToString();
}
public static void ReportRemovedCallback(String key, object value,
CacheItemRemovedReason removedReason)
{
_reportRemovedFromCache = true;
CacheReport();
}
}
警告
浙公网安备 33010602011771号