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

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

1、屬性

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

2、方法

方法名稱 說明
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 對象移除指定項。

 

3、靜態字段

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

 

  先來看基本的示例:web

  index.aspx.cs頁面代碼:sql

複製代碼
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;
        }
    }
}
複製代碼

4、文件緩存依賴

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

  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"]);
        }
    }
複製代碼

5、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"]);
        }
    }
複製代碼

6、NoAbsoluteExpiration 滑動過時時間

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

  滑動過時測試,index.aspx.cs:ide

複製代碼
    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 類。

7、緩存的優先級設置

  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

 

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

  這時就要用到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會報,「未將對象引用設置到對象的實例」。

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

9、數據庫依賴緩存

  一、配置的方式(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;

  二、編程的方式(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委託)。

10、組合依賴緩存

  當依賴的內容爲多個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);

 

11、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));

12、清空緩存

  清空緩存主要經過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());
        }
複製代碼

十3、緩存依賴總結

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

  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:  

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

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

  三、 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實例,這樣能夠構成一種很是複雜的樹狀依賴關係。

 
 
分類:  緩存
相關文章
相關標籤/搜索