ASP.net缓存
问题描述:
我已经实现了asp.net缓存。但我越来越奇怪的结果ASP.net缓存
不像大多数缓存,你试图避免数据库命中量。我试图避免用户对数据库的任何命中。这是B/C页面加载的时间量。它基本上是一个带有大量图表和长时间运行查询的仪表板
我试过几种技术 1)让缓存时间很长,并有一个进度过程到期并获得新的缓存。 2)和RemoveCallback
在我所有的缓存都要经过我创建了一个静态类,第二个选项。目的是为了刷新数据到期。这就是我所说的。
Cache.Insert(dbCacheString, dtNetwork, null, DateTime.Now.AddHours(2),
System.Web.Caching.Cache.NoSlidingExpiration, CacheItemPriority.High,
new CacheItemRemovedCallback(CacheManager.CacheRemovedCallback));
public static class CacheManager
{
private static Hashtable times = new Hashtable();
private static bool isRefreshingCache = false;
public static void CacheRemovedCallback(String key, object value,
CacheItemRemovedReason removedReason)
{
RefreshCache(key);
}
public static void StartCache()
{
string lcUrl = "http://localhost/ratingspage/";
// *** Establish the request
try
{
WebClient client = new WebClient();
client.Credentials = new NetworkCredential("xxx", "xxx",
"xxx");
byte[] myDataBuffer = client.DownloadData(lcUrl);
}
catch (Exception ex)
{
ErrHandler.WriteError(ex.Message + "\n" +
ex.StackTrace.ToString());
LogUtil.LogDebugMessages(ex.Message + ":" +
ex.StackTrace.ToString());
}
}
public static void RefreshCache(string key)
{
string controlname = "";
if (key.ToLower().StartsWith("control:"))
{
string[] tmp = key.Split(':');
if (tmp.Length > 1)
controlname = tmp[1];
else
return;
}
else
return;
string lcUrl = "http://localhost/ratingspage/Admin/" + "
"LoadControl.aspx?CachingSpider=true&Control=" + controlname;
string lcHtml = isRefreshingCache.ToString();
// *** Establish the request
if (!isRefreshingCache)
{
isRefreshingCache = true;
lcHtml = isRefreshingCache.ToString();
try
{
WebClient client = new WebClient();
client.Credentials = new NetworkCredential("xxx",
"xxx", "xxx");
byte[] myDataBuffer = client.DownloadData(lcUrl);
lcHtml = Encoding.ASCII.GetString(myDataBuffer);
}
catch (Exception ex)
{
lcHtml = ex.Message;
isRefreshingCache = false;
ErrHandler.WriteError(ex.Message + "\n" +
ex.StackTrace.ToString());
LogUtil.LogDebugMessages(ex.Message + ":" +
ex.StackTrace.ToString());
}
isRefreshingCache = false;
}
MailMessage mail = new MailMessage(
new MailAddress("[email protected]"),
new MailAddress("[email protected]"));
mail.Subject = "Cache Expire: " + key;
mail.Body = string.Format("The Key {0} has expired at {1}",
key, DateTime.Now.ToShortDateString() + " " +
DateTime.Now.ToShortTimeString()) + "\nRefreshing Cache: " +
lcHtml;
SmtpClient smtp = new SmtpClient("mercury.utg.uvn.net");
mail.IsBodyHtml = false;
try
{
smtp.Send(mail);
}
catch (Exception ex)
{
ErrHandler.WriteError(ex.Message + "\n" +
ex.StackTrace.ToString());
LogUtil.LogDebugMessages(ex.Message + ":" +
ex.StackTrace.ToString());
}
}
}
由于某种原因,当我转到页面时。有时数据被缓存,有时不是。是不是有什么错在这里
我试图应用面料,但因为服务器没有IIS 7我不能够使用
答
答
在我看来,你可能在你的RefreshCache调用中有竞争条件。检查出这个伟大的答案如何处理同步的建议:
C# version of java's synchronized keyword?
如果我是你,我就简化了我的代码。你只有真正需要:
- 当应用程序启动时,加载缓存
- 当缓存过期,重新加载它
- 如果用户试图访问缓存的对象和遗漏,睡自己的线程的第二和再次检查
+0
我不认为这是同步问题。这些项目最初得到缓存,但问题是它不会长时间保留在缓存中。我将超时设置为24小时,并在一小时内过期。我尝试在web.config中使用
你确定你是不是重新启动访问的应用程序域(即按F5调试将清除缓存)。 – Paddy 2011-03-14 14:15:30
只是一些建议,我认为你可以通过不将应用程序代码与缓存管理器相互关联来改善这一点。 CacheManager应该在你使用的任何底层缓存系统(redis,other)中获取/设置键/值。在您现有的业务逻辑中,例如,您将获取用户,然后检查缓存,如果它从数据库中检索为空,则放入缓存并返回项目。如果缓存确实包含用户,那么您只需从缓存中返回用户并跳过您的数据库查询。 – 2015-11-18 18:25:30