我有一个下面详细介绍的测试工具。这在页面上有两个标签,这些标签在page_load中设置,由于更新面板和计时器而每秒都会被触发。
Label1设置为存储在Cache中的日期时间值。 Label2设置为当前日期时间。
从现在开始,缓存设置的绝对到期时间为5秒,缓存上有一个更新回调,用于重新设置日期时间并使其有效5秒钟。
我遇到的问题是我每隔20秒就会看到缓存更新,而不是像我期望的那样每隔5秒更新一次。如果我将时间设置为30秒,则每40秒更新一次。
这似乎表明缓存每20秒才会过期。有谁知道减少这个时间的方法?如果我只是在5秒到期时插入缓存而没有回调,那么它就像我期望的那样工作,并且每5秒就被移除一次。
ASPX:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="CacheTest.aspx.cs" Inherits="CacheTest" %>
<!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>Cache Test</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text="" />
<br />
<asp:Label ID="Label2" runat="server" Text="" />
<asp:Timer ID="Timer1" Interval="1000" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
代码背后:
using System;
using System.Web;
using System.Web.Caching;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class CacheTest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
DateTime CachedDateTime = (DateTime)(Cache["DateTime"] ?? DateTime.MinValue);
if (CachedDateTime == DateTime.MinValue)
{
CachedDateTime = System.DateTime.Now;
Cache.Insert("DateTime", CachedDateTime, null, DateTime.Now.AddSeconds(5), Cache.NoSlidingExpiration, CacheDateTimeUpdateCallback);
}
Label1.Text = CachedDateTime.ToString();
Label2.Text = DateTime.Now.ToString();
}
private void CacheDateTimeUpdateCallback(string key, CacheItemUpdateReason cacheItemUpdateReason, out object value, out CacheDependency dependencies, out DateTime absoluteExipriation, out TimeSpan slidingExpiration)
{
value = System.DateTime.Now;
dependencies = null;
absoluteExipriation = DateTime.Now.AddSeconds(5);
slidingExpiration = Cache.NoSlidingExpiration;
}
}
答案 0 :(得分:2)
您发布的代码存在的一个问题是,您在回调方法中将DateTime
放入缓存中,但在Page_Load中检查Nullable<DateTime>
。
话虽如此,这不是问题所在。在使用Reflector快速查看之后,它看起来像是Cache实现的一个怪癖:当你使用回调时,它会从每20秒运行一次的Timer中调用。
我会推测原因与重入有关。没有什么可以阻止您从回调方法中访问缓存。当它在尝试删除项目的过程中这样做可能不安全(例如,如果您尝试访问缓存项目时它正在删除,则可能存在无限循环)。
因此,当您有回调时,实现将延迟删除缓存项,直到其计时器运行。