2011-03-14 80 views
0

我已经实现了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我不能够使用

+0

你确定你是不是重新启动访问的应用程序域(即按F5调试将清除缓存)。 – Paddy 2011-03-14 14:15:30

+0

只是一些建议,我认为你可以通过不将应用程序代码与缓存管理器相互关联来改善这一点。 CacheManager应该在你使用的任何底层缓存系统(redis,other)中获取/设置键/值。在您现有的业务逻辑中,例如,您将获取用户,然后检查缓存,如果它从数据库中检索为空,则放入缓存并返回项目。如果缓存确实包含用户,那么您只需从缓存中返回用户并跳过您的数据库查询。 – 2015-11-18 18:25:30

回答

0

你可以进入高速缓存中的数据量可能是问题。

如果缓存已满,那么数据显然不会被缓存。

您可以使用process monitor检查您的内存分配情况,查看“Cache Total Entries”。

+0

我该如何检查。我找不到任何东西 – H20rider 2011-03-14 17:55:27

+0

看看这个 - http://msdn.microsoft.com/en-us/library/ms972959.aspx#monitor_perf_topic9它应该有帮助 – 2011-03-15 13:01:00

+0

谢谢。我想我有一个想法,为什么我失去了我的缓存。我查看了事件查看器,发现我有一个.net 4堆栈溢出。我仍试图找出这个问题。 – H20rider 2011-03-18 13:14:30

0

在我看来,你可能在你的RefreshCache调用中有竞争条件。检查出这个伟大的答案如何处理同步的建议:

C# version of java's synchronized keyword?

如果我是你,我就简化了我的代码。你只有真正需要:

  1. 当应用程序启动时,加载缓存
  2. 当缓存过期,重新加载它
  3. 如果用户试图访问缓存的对象和遗漏,睡自己的线程的第二和再次检查
+0

我不认为这是同步问题。这些项目最初得到缓存,但问题是它不会长时间保留在缓存中。我将超时设置为24小时,并在一小时内过期。我尝试在web.config中使用 H20rider 2011-03-15 22:50:38