1. 程式人生 > >System.Web.Caching.Cache類 緩存 各種緩存依賴

System.Web.Caching.Cache類 緩存 各種緩存依賴

media tput cond test table read dict for private

https://www.cnblogs.com/kissdodog/archive/2013/05/07/3064895.html

Cache類,是一個用於緩存常用信息的類。HttpRuntime.Cache以及HttpContext.Current.Cache都是該類的實例。

一、屬性

屬性 說明
Count 獲取存儲在緩存中的項數。
EffectivePercentagePhysicalMemoryLimit 獲取在 ASP.NET 開始從緩存中移除項之前應用程序可使用的物理內存百分比。
EffectivePrivateBytesLimit 獲取可用於緩存的字節數。
Item 獲取或設置指定鍵處的緩存項。

二、方法

方法名稱 說明
Add 將指定項添加到 Cache 對象,該對象具有依賴項、到期和優先級策略以及一個委托(可用於在從 Cache 移除插入項時通知應用程序)。
Get 從 Cache 對象檢索指定項。
GetEnumerator 檢索用於循環訪問包含在緩存中的鍵設置及其值的字典枚舉數。
Insert(String, Object) 向 Cache 對象插入項,該項帶有一個緩存鍵引用其位置,並使用 CacheItemPriority 枚舉提供的默認值。
Insert(String, Object, CacheDependency) 向 Cache 中插入具有文件依賴項或鍵依賴項的對象。
Insert(String, Object, CacheDependency, DateTime, TimeSpan) 向 Cache 中插入具有依賴項和到期策略的對象。
Insert(String, Object, CacheDependency, DateTime, TimeSpan, CacheItemUpdateCallback) 將對象與依賴項、到期策略以及可用於在從緩存中移除項之前通知應用程序的委托一起插入到 Cache 對象中。
Insert(String, Object, CacheDependency, DateTime, TimeSpan, CacheItemPriority, CacheItemRemovedCallback) 向 Cache 對象中插入對象,後者具有依賴項、到期和優先級策略以及一個委托(可用於在從 Cache 移除插入項時通知應用程序)。
Remove 從應用程序的 Cache 對象移除指定項。

三、靜態字段

名稱 說明
NoAbsoluteExpiration 用於 Insert 方法調用中的 absoluteExpiration 參數中以指示項從不到期。 此字段為只讀。
NoSlidingExpiration 用作 Insert 或 Add 方法調用中的 slidingExpiration 參數,以禁用可調到期。 此字段為只讀。

  先來看基本的示例:

  index.aspx.cs頁面代碼:

技術分享圖片
namespace WebApplication1
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Person p = new Person();
            p.Id = 1;
            p.Name = "諸葛亮";

            Cache cache = HttpRuntime.Cache;
            cache.Insert("AA",p);
            cache.Insert("BB","字符串");
            
            Response.Write(cache.Get("BB").ToString());     //輸出 字符串
            Person p2 = cache["AA"] as Person;
            Response.Write(p2.Id + " : " + p2.Name);        //輸出 1 : 諸葛亮
            Response.Write(cache.EffectivePrivateBytesLimit);   //-1 這是一個只讀屬性,那就沒什麽好說了,只能輸出來看看了,但是-1是什麽意思呢?無限嗎
            Response.Write(cache.EffectivePercentagePhysicalMemoryLimit);   //98    開始移除項之前可以使用到98%


            Response.Write(cache.Count);        //輸出 3
            Response.Write(cache["BB"]);        //輸出 字符串 支持索引器式的讀取

            cache.Remove("BB");        //從cache中移除一項
            Response.Write("~~~" + cache["BB"] + "~~~");    //移除了輸出 null,但程序不報錯

            foreach (var obj in cache)
            {
                Response.Write(obj.GetType() + "<br/>");    //輸出不知道什麽鳥東西
            }
        }
    }

    public class Person
    {
        public int Id
        {
            get;
            set;
        }

        public string Name
        {
            get;
            set;
        }
    }
}
技術分享圖片

四、文件緩存依賴

  當被依賴的文件更改時,緩存會立即被清空:

  index.aspx.cs代碼:

技術分享圖片
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Cache cache = HttpContext.Current.Cache;
            //文件緩存依賴
            cache.Insert("CC", "依賴項測試", new CacheDependency(@"D:\123.txt"));
            //這時候在about.aspx頁面添加一行代碼,當更改一下D:123.txt時,cache["cc"]會立即被清空
        }
    }
技術分享圖片

  about.aspx.cs代碼:

技術分享圖片
    public partial class About : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //直接打開本頁面,輸出緩存依賴項測試
            //當更改D:\123.txt之後,在刷新,輸出空,表明該Cache是依賴於D:\123.txt的
            Response.Write(HttpContext.Current.Cache["CC"]);
        }
    }
技術分享圖片

五、NoSlidingExpiration 絕對過期時間

  NoSlidingExpiration  絕對過期時間,當超過設定時間,立即移除。

  下面來看下絕對過期時間的示例,index.aspx.cs:

技術分享圖片
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Cache cache = HttpContext.Current.Cache;
            //30秒後就到期,立即移除,沒商量
            cache.Insert("DD", "絕對過期測試", null, DateTime.Now.AddSeconds(5), System.Web.Caching.Cache.NoSlidingExpiration);
        }
    }
技術分享圖片

  about.aspx.cs:

技術分享圖片
    public partial class About : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //先打開index.aspx添加到緩存 然後立即打開本頁面,輸出 絕對過期測試
            //持續刷新5秒後,不會再輸出  絕對過期測試
            Response.Write(HttpContext.Current.Cache["DD"]);
        }
    }
技術分享圖片

六、NoAbsoluteExpiration 滑動過期時間

  NoAbsoluteExpiration  當超過設定時間沒再使用時,才移除緩存

  滑動過期測試,index.aspx.cs:

技術分享圖片
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Cache cache = HttpContext.Current.Cache;
            //彈性過期時間,當緩存沒使用10秒就過期
            cache.Insert("DD", "滑動過期測試", null, System.Web.Caching.Cache.NoAbsoluteExpiration,TimeSpan.FromSeconds(10));
        }
    }
技術分享圖片

  about.aspx.cs:

技術分享圖片
    public partial class About : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            //直接打開本頁面,輸出彈性過期測試
            //如果一直不停地刷新,都會繼續輸出,但是當超過10秒後再刷新,不會再輸出   滑動緩存測試
            Response.Write(HttpContext.Current.Cache["DD"]);
        }
    }
技術分享圖片

  註意 當設置絕對到期時間時,請使用 DateTime 結構。當設置彈性過期時間時,請使用 TimeSpan 結構。另外,如果您創建的彈性過期時間小於零或大於一年,則將引發 ArgumentOutOfRangeException 類。

七、緩存的優先級設置

  CacheItemPriority枚舉  設置緩存的優先級

技術分享圖片
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Cache cache = HttpContext.Current.Cache;
            //文件權重級別
            cache.Add("MyData", "緩存重要級別", null, Cache.NoAbsoluteExpiration, TimeSpan.FromSeconds(30), CacheItemPriority.High, null);
        }
    }
技術分享圖片

  該枚舉一共有六級:

技術分享圖片
     //在服務器釋放系統內存時,具有該優先級級別的緩存項最有可能被從緩存刪除。
        Low = 1,//在服務器釋放系統內存時,具有該優先級級別的緩存項比分配了 System.Web.Caching.CacheItemPriority.Normal
        //優先級的項更有可能被從緩存刪除。
        BelowNormal = 2,//在服務器釋放系統內存時,具有該優先級級別的緩存項很有可能被從緩存刪除,其被刪除的可能性僅次於具有 System.Web.Caching.CacheItemPriority.Low
        Normal = 3,//緩存項優先級的默認值為 System.Web.Caching.CacheItemPriority.Normal。
        Default = 3,//在服務器釋放系統內存時,具有該優先級級別的緩存項被刪除的可能性比分配了 System.Web.Caching.CacheItemPriority.Normal
        //優先級的項要小。
        AboveNormal = 4,//在服務器釋放系統內存時,具有該優先級級別的緩存項最不可能被從緩存刪除。
        High = 5,//在服務器釋放系統內存時,具有該優先級級別的緩存項將不會被自動從緩存刪除。但是,具有該優先級級別的項會根據項的絕對到期時間或可調整到期時間與其他項一起被移除
        NotRemovable = 6,
技術分享圖片
優先級
Low=1
BelowNormal=2
Normal=3
Default=3
AboveNormal=4
High=5
NotRemoveable=6

八、當緩存被移除時,通知程序

  這時就要用到Add的最後一個參數,委托了:

  index.aspx.cs代碼如下:

技術分享圖片
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Cache cache = HttpRuntime.Cache;
            //文件權重級別
            cache.Add("MyData", "緩沖移除通知", null, DateTime.Now.AddSeconds(10) ,Cache.NoSlidingExpiration,CacheItemPriority.Low, Show);
        }

        public void Show(string key, object value, CacheItemRemovedReason reason)
        {
            Cache cache = HttpRuntime.Cache;
            Cache.Insert("MyData", "緩存被清空啦!緩存被清空啦!緩存被清空啦!緩存被清空啦!緩存被清空啦!緩存被清空啦!緩存被清空啦!");
        }
    }
技術分享圖片

  about.aspx.cs代碼如下:

技術分享圖片
    public partial class About : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Response.Write(HttpRuntime.Cache["MyData"]);
        }
    }
技術分享圖片

  此處實現的效果時:第一次打開index.aspx(讓程序加入數據到緩存),然後打開about.aspx顯示出“緩存移除通知”,10秒後再刷新,顯示

“緩存被清空啦!緩存被清空啦!緩存被清空啦!緩存被清空啦!緩存被清空啦!緩存被清空啦!緩存被清空啦!”  經測試,以上程序的Cache最好還是用HttpRuntime的,否則沒有請求時HttpContext會報,“未將對象引用設置到對象的實例”。

  這就是被清空時會自動調用委托程序進行處理,你可以再次將數據添加進入緩存,或者記錄到日誌等等一系列操作。

九、數據庫依賴緩存

  1、配置的方式(sqlserver2000) SqlDependency第一個構造函數。

  首先一個WebForm的Web.Config中的配置文件修改如下:

技術分享圖片
  <connectionStrings>
    <add name="ApplicationServices"
         connectionString="Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;"
         providerName="System.Data.SqlClient" />
  </connectionStrings>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
    <caching>
      <sqlCacheDependency enabled="true" pollTime="1000">  //此行配置的意思是,開啟數據庫緩存,輪詢時間為1秒,這是為了能夠快速看到更改效果
        <databases>
          <add connectionStringName="ApplicationServices" name="con"/>
        </databases>
      </sqlCacheDependency>
    </caching>
    </system.web>
技術分享圖片

  修改Global.asax.cs文件代碼如下:

技術分享圖片
        void Application_Start(object sender, EventArgs e)
        {
            string connString = System.Web.Configuration.WebConfigurationManager.ConnectionStrings["ApplicationServices"].ConnectionString;
       SqlCacheDependencyAdmin.EnableNotifications(connectionString);     //啟動數據庫的數據緩存依賴功能                      
       SqlCacheDependencyAdmin.EnableTableForNotifications(connectionString, table); //啟用數據表緩存 }
技術分享圖片

  Index.aspx.cs文件代碼如下:

        protected void Page_Load(object sender, EventArgs e)
        {
            SqlCacheDependency dependency = new SqlCacheDependency("con", "Record");
            // 新增或修改一條緩存記錄
            HttpRuntime.Cache.Insert("MyData", "數據庫緩存測試", dependency);
        }

  About.aspx.cs文件代碼如下:

        protected void Page_Load(object sender, EventArgs e)
        {
            Response.Write(HttpRuntime.Cache["MyData"]);
        }

  次數實現的效果時,打開Index.aspx.cs文件將數據添加到緩存後,然後打開about.asox,頁面輸出"數據庫緩存測試",這時候更改一下數據庫的Record表,再刷新about.aspx頁面,上一次輸出的內容沒有了。

System.Data.SqlClient.SqlDependency.Start(connString);
System.Data.SqlClient.SqlDependency.Stop(connString);

  這兩行代碼不一定要放在Global.asax.cs裏面,在代碼執行之前和執行之後就OK了。

  註意,在這個例子當中,數據庫要開啟Service Broker

  檢測是否已經啟用Service Broker
Select DATABASEpRoPERTYEX(‘數據庫名稱‘,‘IsBrokerEnabled‘)          -- 1 表示已經啟用 0 表示沒有啟用
  啟用Servicce Broker
ALTER DATABASE NX SET ENABLE_BROKER;
如果啟動時,一直顯示正在執行查詢,那麽用一下這條語句
ALTER DATABASE NX SET NEW_BROKER WITH ROLLBACK IMMEDIATE;
ALTER DATABASE NX SET ENABLE_BROKER;

  2、編程的方式(sqlserver2008),第二個構造函數SqlDependency(sqlcommand sqlcom)

  index.aspx.cs文件代碼如下:

技術分享圖片
        protected void Page_Load(object sender, EventArgs e)
        {
            SqlCacheDependency dependency;
            SqlConnection conn = new SqlConnection(@"Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;");
            using (conn)
            {
                string sql = "select name from dbo.record";
                SqlCommand cmd = new SqlCommand(sql, conn);
                dependency = new SqlCacheDependency(cmd);
                SqlDataAdapter adapter = new SqlDataAdapter(cmd);   //這裏要特別註意,你的cmd一定要執行過,或者說Execute過,真正從數據庫裏面取出過數據
                DataSet ds = new DataSet();
                adapter.Fill(ds);   //這裏才是cmd真正執行的地方,註意真正執行要在綁定dependency之後
            }
            Response.Write("開始!");
            Cache.Insert("MyData", "數據庫依賴測試", dependency);
            Response.Write("完成!");
        }
技術分享圖片

  about.aspx.cs代碼文件如下:

技術分享圖片
    public partial class About : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (HttpRuntime.Cache["MyData"] != null)
            {
                Response.Write(HttpRuntime.Cache["MyData"]);
            }
            else
            {
                Response.Write("緩存已不存在!");
            }
        }
    }
技術分享圖片

  實現的效果一樣是,打開index.aspx文件,再打開about.aspx文件,頁面輸出"緩存測試結果",當更改表record之後,再刷新about.aspx頁面,緩存被清空。

  再來一個例子,上次又是頁面啥的,這次用十幾行代碼說明,這個東東實現的要點:

技術分享圖片
        static void Main(string[] args)
        {
            Cache cache = HttpRuntime.Cache;
            System.Data.SqlClient.SqlDependency.Start(@"Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;");

            // 創建緩存依賴  
            SqlConnection conn = new SqlConnection(@"Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;");
            SqlCommand command = new SqlCommand("select Id,name from dbo.Record", conn);

            SqlCacheDependency dependency = new SqlCacheDependency(command);    //註意,創建的command與SqlCacheDependency綁定要在command執行之前
            SqlDataAdapter adapter = new SqlDataAdapter(command);   
            DataSet ds = new DataSet();
            adapter.Fill(ds);    //這裏要特別註意,Fill才是真正執行
            
            cache.Insert("DD", "數據庫依賴測試", dependency);
            Console.WriteLine(cache["DD"]);
            Thread.Sleep(20000);     //暫停20秒給你更改一下數據庫
            if (cache["DD"] == null)
            {
                Console.WriteLine("數據庫已經修改過了!");               
            }
            Console.ReadKey();
            System.Data.SqlClient.SqlDependency.Stop(@"Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;");
        }
技術分享圖片

  在途中,我會隨便修改一下Record表,輸出結果如下:

  技術分享圖片

  再來一次數據庫緩存依賴,回調函數的例子:

技術分享圖片
    public class Program
    {
        static void Main(string[] args)
        {
            Cache cache = HttpRuntime.Cache;
            System.Data.SqlClient.SqlDependency.Start(@"Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;");

            // 創建緩存依賴  
            SqlConnection conn = new SqlConnection(@"Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;");
            SqlCommand command = new SqlCommand("select Id,name from dbo.Record", conn);

            SqlCacheDependency dependency = new SqlCacheDependency(command);    //註意,創建的command與SqlCacheDependency綁定要在command執行之前
            SqlDataAdapter adapter = new SqlDataAdapter(command);   
            DataSet ds = new DataSet();
            adapter.Fill(ds);    //這裏要特別註意,Fill才是真正執行


            CacheItemRemovedCallback callback = new CacheItemRemovedCallback(RemovedCallback);
            cache.Insert("DD", "數據庫依賴測試", dependency, DateTime.Now.AddDays(1), TimeSpan.Zero, CacheItemPriority.Default, callback);
            Console.WriteLine(cache["DD"]);
            Thread.Sleep(15000);     //暫停15秒給你更改一下數據庫
            if (cache["DD"] == null)
            {
                Console.WriteLine("數據庫已經修改過了!");               
            }
            Console.ReadKey();
            System.Data.SqlClient.SqlDependency.Stop(@"Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;");
        }

        public static void RemovedCallback(string key, object value, CacheItemRemovedReason reason)
        {
            Console.WriteLine("緩存被移除!");
            Console.WriteLine(reason.ToString());
        }
    }
技術分享圖片

  輸出結果如下:

  技術分享圖片

  這裏要補充幾點:當設置為絕對過期時,後面那個TimeSpan參數要設為TimeSpan.Zero。另外,重載中還有一個方法之前在緩存移除前執行回調函數的,而剛剛那個是緩存數據被移除之後執行的。

  CacheItemUpdateCallback  緩存數據移除之前調用;

  CacheItemRemoceCallback  緩存數據移除之後調用;

  再來寫一個:

技術分享圖片
    public class Program
    {
        static void Main(string[] args)
        {
            Cache cache = HttpRuntime.Cache;
            System.Data.SqlClient.SqlDependency.Start(@"Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;");

            // 創建緩存依賴  
            SqlConnection conn = new SqlConnection(@"Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;");
            SqlCommand command = new SqlCommand("select Id,name from dbo.Record", conn);

            SqlCacheDependency dependency = new SqlCacheDependency(command);    //註意,創建的command與SqlCacheDependency綁定要在command執行之前
            SqlDataAdapter adapter = new SqlDataAdapter(command);   
            DataSet ds = new DataSet();
            adapter.Fill(ds);    //這裏要特別註意,Fill才是真正執行


            CacheItemUpdateCallback callback = new CacheItemUpdateCallback(RemovedCallback);
            cache.Insert("DD", "數據庫依賴測試", dependency, DateTime.Now.AddDays(1), TimeSpan.Zero, callback);
            Console.WriteLine(cache["DD"]);
            Thread.Sleep(15000);     //暫停15秒給你更改一下數據庫
            if (cache["DD"] == null)
            {
                Console.WriteLine("數據庫已經修改過了!");               
            }
            Console.ReadKey();
            System.Data.SqlClient.SqlDependency.Stop(@"Server=KISSDODOG-PC;Database=Nx;uid=sa;pwd=123;");
        }

        public static void RemovedCallback(string key, CacheItemUpdateReason reason, out object expensiveObject, out CacheDependency dependency, out DateTime absoluteExpiration, out TimeSpan slidingExpiration)
        {
            //   key:要從緩存中移除的項的標識符。
            //   reason:要從緩存中移除項的原因。
            //   expensiveObject:此方法返回時,包含含有更新的緩存項對象。
            //   dependency:此方法返回時,包含定義項對象和文件、緩存鍵、文件或緩存鍵的數組或另一個 System.Web.Caching.CacheDependency 對象之間的依賴項的對象。
            //   absoluteExpiration:此方法返回時,包含對象的到期時間。
            //   slidingExpiration:此方法返回時,包含對象的上次訪問時間和對象的到期時間之間的時間間隔。
            expensiveObject = null;
            dependency = null;
            absoluteExpiration = DateTime.Now;
            slidingExpiration = TimeSpan.Zero;
            Console.WriteLine("緩存馬上被移除!");
            //但是現在還有沒有呢?輸出試試
            Console.WriteLine(HttpRuntime.Cache["DD"]);
            Console.WriteLine(reason.ToString());
        }
    }
技術分享圖片

  輸出結果為:

  技術分享圖片

  看到,在Update這個委托執行時,緩存還是存在的。

  註意:那個SQL語句還是比較嚴格的,主要要符合以下要求

a). 必須設置完全限定名稱的數據表。即表名前面需要加所有者,如dbo.test。

b). 必須明確設置所訪問數據庫列名稱,不能使用“*”。

c). 必須保證不是聚合函數。如COUNT、MAX等。

SQL SERVER 7.0/2000 SQL SERVER 2005
實現機制 輪詢 通知傳遞服務(Service Broker)

是否需要配置啟用

需要

不需要,內置支持

數據更改檢測

限於表級更改監測

表級、行級更改監測

   很明顯,SQL SERVER 2005的緩存機制更加高效。另外,SqlCacheDependency類還特別結合SQL SERVER 2005 進行了優化:

a). 使用SQL SERVER 2005 時,SqlCacheDependency類支持與System.Data.SqlClient.SqlDependency類進行集成。應用程序可創建SqlDependency對象,並通過OnChanged事件處理程序接受通知進行註冊。這樣,應用程序不僅可以使用Sql server 2005的查詢通知機制來監測使用SQL查詢結果無效的數據更改,並將緩存對象從緩存中移除,而且還可以輕松獲取數據更改通知,以便刷新緩存。(從這裏可以看出,當觸發onRemoveCallback委托的時候,數據已經從緩存裏面刪除了,這樣一來可以手動在委托裏面添加緩存,或者幹脆設置成null,讓他下次調用的時候再緩存。)

b). 不僅向應用程序添加緩存依賴項,還可以與@OutputCache指令一起使用,以生成依賴於SqlServer數據庫表的輸出緩存的頁面或用戶控件。對於用戶控件,@OutputCache指令不支持使用SQL SERVER 2005 的查詢通知(即onRemoveCallback委托)。

十、組合依賴緩存

  當依賴的內容為多個Dependency時,可以通過AggregateCacheDependency創建依賴的組合,以便在任何一個依賴項發生變化時,使緩存項失效。
  組合的緩存依賴內部為一個集合,可以保存多個緩存依賴對象,將這些緩存依賴對象作為一個整體應用在緩存項目上,當其中某一個緩存依賴失效的時候,就可以使緩存的數據被丟棄。

  組合依賴緩存示例:

//創建緩存依賴
System.Web.Caching.SqlCacheDependency product = new System.Web.Caching.SqlCacheDependency("northwindcache","products");
System.Web.Caching.SqlCacheDependency category = new System.Web.Caching.SqlCacheDependency("northwindcache","products")
//多個緩存依賴組合成一個依賴對象使用
System.Web.Caching.AggregateCacheDependency acd = new System.Web.Caching.AggregateCacheDependency();
acd.Add(product,category);

十一、System.Web.Caching.Cache Insert和Add方法的區別

  Add方法

object Add(string key, object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback);

  Insert方法

技術分享圖片
void Insert(string key, object value); //永不過期
void Insert(string key, object value, CacheDependency dependencies);  //依賴
void Insert(string key, object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration);//絕對時間過期:
void Insert(string key, object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemUpdateCallback onUpdateCallback);  //依賴+回調
void Insert(string key, object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback);  //依賴+優先級+回調
技術分享圖片

  比較、區別

    a). Insert方法支持5種重載,使用靈活,而Add方法必須提供7個參數;

    b). Add方法可以返回緩存項的數據對象,Insert 返回Void;

    c). 添加重復緩存情況下(Key已存在),Insert會替換該項,而Add方法則不執行任何操作,並返回原來保存的object對象(Update 2014-03-18)。

  過期策略

    a). 永不過期
      Insert(string key, object value);

    b). 絕對時間過期

      DateTime.Now.AddSeconds(10)表示緩存在10秒後過期,TimeSpan.Zero表示不使用平滑過期策略。

      例:Cache.Insert("Data", ds,null, DateTime.Now.AddSeconds(10), TimeSpan.Zero);

    c). 變化時間過期(平滑過期)

      DateTime.MaxValue表示不使用絕對時間過期策略,TimeSpan.FromSeconds(10)表示緩存連續10秒沒有訪問就過期。

      例:Cache.Insert("Data", ds, null, DateTime.MaxValue, TimeSpan.FromSeconds(10));

十二、清空緩存

  清空緩存主要通過Remove()方法,但是只能通過傳入一個Key,清空一個。

  GetEnumerator()方法用於獲取所有緩存項。MoveNext()用於將位置移動到下一個緩存項。

  如果想清空所有緩存,由於Cache類沒有提供RemoveAll()方法,所以可以通過以下方式實現:

技術分享圖片
        IDictionaryEnumerator DicCache = HttpRuntime.Cache.GetEnumerator();
        int count = HttpRuntime.Cache.Count;
        for (int i = 0; i < count; i++)
        {
            DicCache.MoveNext();
            HttpRuntime.Cache.Remove(DicCache.Entry.Key.ToString());
        }
技術分享圖片

十三、緩存依賴總結

  緩存依賴主要有如下技術點

  Dependency依賴:.Net中支持兩種依賴:CacheDependency和SqlDependency(兩者都是Dependency的子類)。從.Net2.0開始,CacheDependency不再是密封的,而是可以繼承的。
   ┠CacheDependency:表示對文件或者目錄的依賴
   ┠SqlDependency:表示基於SQL數據庫的依賴

  過期時間:過期時間分絕對過期時間和滑動過期時間兩種。
   ┠絕對過期時間:為特定時間點,類型為DateTime,如果不使用絕對過期時間,那麽,使用System.Web.Caching.Cache.NoAbsoluteExpiration表示。
   ┠滑動過期時間:為一個事件間隔,類型為TimeSpan,如果不使用滑動過期時間,使用System.Web.Cacheing.NoSlidingExpiration表示。

  刪除通知:.Net提供了一個機制,當被緩存的數據從內存中移除的時候,可以提供一個通知機制,來回調用戶定義的方法,方法必須符合CacheItemRemoveCallback委托的定義。該委托定義如下:

public delegate void CacheItemRemoveCallback(string key,Object value,CacheItemRemovedReason reason)

  其中,CacheItemRemoveReason為緩存項被移除的原因。CacheItemRemovedReason是一個枚舉類型,定義了如下原因:

  1. DependencyChange:由於依賴發生變化被移除;
  2. Expired:由於過期被移除;
  3. Removed:由於調用Insert插入一個同名的緩存項或者調用Remove失效被移除;
  4. Underused:系統移除;

註意:

  • 回調的時機是不可預知的,不能假定回調發生時,回調方法的執行線程存在HttpContext的上下文,為了在沒有請求上下文的時候取得對Cache對象的引用,可以通過HttpRuntime的Cache屬性來使用應用程序的Cache。
  • 不能在頁面上使用實例方法來作為回調方法,當在頁面上使用回調方法時,由於指向回調方法的引用會阻止垃圾回收機制,因此會造成內存很快耗光。
  • 一般通過在自定義類的靜態方法實現回調方法,或者使用頁面對象的靜態方法的實現。

PS:  

  1、 CacheDependency是AggregateCacheDependency和SqlCacheDependency的父類。主要用於在應用程序數據緩存對象與文件、緩存鍵、文件或緩存鍵的數組或另外一個CacheDependency對象之間建立依賴關系。CacheDependency監視依賴關系比便在任何對象更改時自動移除緩存對象。CacheDependency可以監測一組(到文件或目錄的)文件路徑的更改情況。

  2、 AggregateCacheDependency主要用於實現聚合緩存依賴。如一筆數據同時對兩個表進行緩存依賴,一旦其中任何一個表數據更改緩存將失效。

  3、 SqlCacheDependency將應用程序數據緩存對象、頁面輸出緩存、數據源控件等與指定SQL Server數據庫表或Sql Server 2005 查詢結果之間建立緩存依賴關系,在表發生更改(Sql Server 2005 行級別更改)時,自動從緩存中刪除和重新添加與該表關聯的緩存對象。一般而言:

  • SqlCacheDependency (SqlCommand) 用於SQL SERVER 2005
  • SqlCacheDependency (數據庫名, 表名) 用於SQL SERVER 7.0/2000

  有以下幾條緩存數據的規則。:
  第一,數據可能會被頻繁的被使用,這種數據可以緩存。
  第二,數據的訪問頻率非常高,或者一個數據的訪問頻率不高,但是它的生存周期很長(很少變動),這樣的數據最好也緩存起來。
  第三,是一個常常被忽略的問題,有時候我們緩存了太多數據,通常在一臺X86的機子上,如果你要緩存的數據超過800M的話,就會出現內存溢出的錯誤。所以說緩存是有限的。換名話說,你應該估計緩存集的大小,把緩存集的大小限制在10以內,否則它可能會出問題。在Asp.net中,如果緩存過大的話也會報內存溢出錯誤,特別是如果緩存大的DataSet對象的時候。

  你應該認真分析你的程序。根據實際情況來看哪裏該用,哪裏不該用。如:Cache用得過多也會增大服務器的壓力。整頁輸出緩存,又會影響數據的更新。 如果真的需要緩存很大量的數據,可以考慮靜態技術。

  CacheDependency還支持【嵌套】,即:CacheDependency的構造函數中支持傳入其它的CacheDependency實例,這樣可以構成一種非常復雜的樹狀依賴關系。

System.Web.Caching.Cache類 緩存 各種緩存依賴