2011-03-14 81 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