Cache及(HttpRuntime.Cache與HttpContext.Current.Cache)


本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/avon520/archive/2009/11/25/4872704.aspx

.NET中Cache有兩種調用方式:HttpContext.Current.Cache 和 HttpRuntime.Cache,這兩種方式有什么區別呢?我們先看MSDN上的解釋:
      HttpContext.Current.Cache:為當前 HTTP 請求獲取Cache對象。
      HttpRuntime.Cache:獲取當前應用程序的Cache。

      我們再用.NET Reflector工具看看HttpContext.Cache和HttpRuntime.Cache的實現:

HttpContext.Cache和HttpRuntime.Cache實現
    //System.Web.HttpContext.Cache屬性實現
    public sealed class HttpContext
    {
        public Cache Cache
        {
            get
            {
                return HttpRuntime.Cache;
            }
        }
    }

    //System.Web.HttpRuntime.Cache屬性實現
    public sealed class HttpRuntime
    {
        public static Cache Cache
        {
            get
            {
                if (AspInstallDirectoryInternal == null)
                {
                    throw new HttpException(SR.GetString("Aspnet_not_installed", new object[] { VersionInfo.SystemWebVersion }));
                }
                Cache cache = _theRuntime._cachePublic;
                if (cache == null)
                {
                    CacheInternal cacheInternal = CacheInternal;
                    CacheSection cacheSection = RuntimeConfig.GetAppConfig().Cache;
                    cacheInternal.ReadCacheInternalConfig(cacheSection);
                    _theRuntime._cachePublic = cacheInternal.CachePublic;
                    cache = _theRuntime._cachePublic;
                }
                return cache;
            }
        }
    }

       通過上面的代碼我們可以看出:HttpContext.Current.Cache是調用HttpRuntime.Cache實現的,兩者指向同一Cache對象。那么兩者到底有沒有區別的?既然兩個指向的是同一Cache對象,兩者的差別只能出現在HttpContext和HttpRuntime上了。我們再來看看MSDN中HttpContext和HttpRuntime的定義。
      HttpContext:封裝有關個別HTTP請求的所有HTTP特定的信息,HttpContext.Current為當前的HTTP請求獲取HttpContext對象。

 

      HttpRuntime:為當前應用程序提供一組ASP.NET運行時服務。

      由上面的定義可以看出:HttpRuntime.Cache相當於就是一個緩存具體實現類,這個類雖然被放在了System.Web命名空間下,但是非Web應用下也是可以使用;HttpContext.Current.Cache是對上述緩存類的封裝,由於封裝到了HttpContext類中,局限於只能在知道HttpContext下使用,即只能用於Web應用。

      下面的例子可以很好的說明這一點:

HttpContext.Cache和HttpRuntime.Cache的示例
    class CacheTest
    {
        static void Main(string[] args)
        {       
            System.Web.Caching.Cache httpRuntimeCache = System.Web.HttpRuntime.Cache;
            httpRuntimeCache.Insert("httpRuntimeCache", "I am stored in HttpRuntime.Cache");

            if (httpRuntimeCache != null)
            {
                Console.WriteLine("httpRuntimeCache:" + httpRuntimeCache["httpRuntimeCache"]);
            }

            System.Web.HttpContext httpContext = System.Web.HttpContext.Current;
            if (httpContext == null)
            {
                Console.WriteLine("HttpContext object is null in Console Project");
            }
            else
            {
                System.Web.Caching.Cache httpContextCache = httpContext.Cache;
                httpContextCache.Insert("httpContextCache", "I am stored in HttpRuntime.Cache");
                if (httpContextCache == null)
                {
                    Console.WriteLine("httpContextCache is null");
                }
            }
             
            Console.ReadLine();
        }
    }

      輸出結果:httpRuntimeCache:I am stored in HttpRuntime.Cache
      HttpContext object is null in Console Project

      綜上:我們在使用Cache時,盡量使用HttpRuntime.Cache,既能減少出錯,也減少了一次函數調用。

      參考資料:HttpRuntime.Cache 與HttpContext.Current.Cache的疑問,HttpRuntime.Cache vs. HttpContext.Current.Cache

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/avon520/archive/2009/11/25/4872704.aspx

 

以下轉自轉自:http://www.cnblogs.com/McJeremy/archive/2008/12/01/1344660.html

 

我們在.NET運用中經常用到緩存(Cache)對象。
除了System.Web.Caching下的Cache外,我們還可以用到HttpContext.Current.Cache以及HttpRuntime.Cache
那么,HttpContext.Current.Cache以及HttpRuntime.Cache有什么區別呢?
從MSDN上的解釋可以看出,HttpRuntime.Cache是應用程序級別的,而HttpContext.Current.Cache是針對當前WEB上下文定義的。
然而,實際上,這二個都是調用的同一個對象,不同的是:HttpRuntime下的除了WEB中可以使用外,非WEB程序也可以使用。
而HttpContext則只能用在WEB中。
因此,在可能的情況下,我們盡可能使用HttpRuntime(然而,在不同應用程序之間如何調用也是一個問題)。
=====
以下是摘錄自:http://www.cnblogs.com/caoxch/archive/2006/11/20/566236.html
的對Cache的詳細介紹

ASP.NET 緩存概述 

 

通常,應用程序可以將那些頻繁訪問的數據,以及那些需要大量處理時間來創建的數據存儲在內存中,從而提高性能。例如,如果應用程序使用復雜的邏輯來處理大量數據,然后再將數據作為用戶頻繁訪問的報表返回,避免在用戶每次請求數據時重新創建報表可以提高效率。同樣,如果應用程序包含一個處理復雜數據但不需要經常更新的頁,則在每次請求時服務器都重新創建該頁會使工作效率低下。

在這些情況下,為了幫助您提高應用程序的性能,ASP.NET 使用兩種基本的緩存機制來提供緩存功能。第一種機制是應用程序緩存,它允許您緩存所生成的數據,如 DataSet 或自定義報表業務對象。第二種機制是頁輸出緩存,它保存頁處理輸出,並在用戶再次請求該頁時,重用所保存的輸出,而不是再次處理該頁。

應用程序緩存

應用程序緩存提供了一種編程方式,可通過鍵/值對將任意數據存儲在內存中。使用應用程序緩存與使用應用程序狀態類似。但是,與應用程序狀態不同的是,應用程序緩存中的數據是易失的,即數據並不是在整個應用程序生命周期中都存儲在內存中。使用應用程序緩存的優點是由 ASP.NET 管理緩存,它會在項過期、無效、或內存不足時移除緩存中的項。還可以配置應用程序緩存,以便在移除項時通知應用程序。有關更多信息,請參見緩存應用程序數據

使用應用程序緩存的模式是,確定在訪問某一項時該項是否存在於緩存中,如果存在,則使用。如果該項不存在,則可以重新創建該項,然后將其放回緩存中。這一模式可確保緩存中始終有最新的數據。

有關更多信息,請參見如何:檢索緩存項的值

頁輸出緩存

頁輸出緩存在內存中存儲處理后的 ASP.NET 頁的內容。這一機制允許 ASP.NET 向客戶端發送頁響應,而不必再次經過頁處理生命周期。頁輸出緩存對於那些不經常更改,但需要大量處理才能創建的頁特別有用。例如,如果創建大通信量的網頁來顯示不需要頻繁更新的數據,頁輸出緩存則可以極大地提高該頁的性能。可以分別為每個頁配置頁緩存,也可以在 Web.config 文件中創建緩存配置文件。利用緩存配置文件,只定義一次緩存設置就可以在多個頁中使用這些設置。

頁輸出緩存提供了兩種頁緩存模型:整頁緩存和部分頁緩存。整頁緩存允許將頁的全部內容保存在內存中,並用於完成客戶端請求。部分頁緩存允許緩存頁的部分內容,其他部分則為動態內容。有關更多信息,請參見緩存 ASP.NET 頁

部分頁緩存可采用兩種工作方式:控件緩存和緩存后替換。控件緩存有時也稱為分段緩存,這種方式允許將信息包含在一個用戶控件內,然后將該用戶控件標記為可緩存的,以此來緩存頁輸出的部分內容。這一方式可緩存頁中的特定內容,並不緩存整個頁,因此每次都需重新創建整個頁。例如,如果要創建一個顯示大量動態內容(如股票信息)的頁,其中有些部分為靜態內容(如每周總結),這時可以將靜態部分放在用戶控件中,並允許緩存這些內容。

緩存后替換與控件緩存正好相反。這種方式緩存整個頁,但頁中的各段都是動態的。例如,如果要創建一個在規定時間段內為靜態的頁,則可以將整個頁設置為進行緩存。如果向頁添加一個顯示用戶名的 Label控件,則對於每次頁刷新和每個用戶而言,Label 的內容都將保持不變,始終顯示緩存該頁之前請求該頁的用戶的姓名。但是,使用緩存后替換機制,可以將頁配置為進行緩存,但將頁的個別部分標記為不可緩存。在此情況下,可以向不可緩存部分添加 Label 控件,這樣將為每個用戶和每次頁請求動態創建這些控件。有關更多信息,請參見緩存 ASP.NET 頁的某些部分

根據請求參數緩存頁

除緩存頁的單一版本外,ASP.NET 頁輸出緩存還提供了一些功能,可以創建根據請求參數的不同而不同的頁的多個版本。有關更多信息,請參見緩存頁的多個版本

自動移除數據

出於以下原因之一,ASP.NET 可以從緩存中移除數據:

  • 由於服務器上的內存不足,開始一個稱為“清理”的過程。

  • 由於緩存中的項已過期。

  • 由於項的依賴項發生了更改。

為了幫助管理緩存項,在將項從緩存中移除時,ASP.NET 會通知應用程序。

清理

清理是在內存不足時從緩存中刪除項的過程。如果某些項在一段時間內未被訪問,或是在添加到緩存中時被標記為低優先級,則這些項會被移除。ASP.NET 使用 CacheItemPriority 對象來確定要首先清理的項。有關更多信息,請參見如何:將項添加到緩存中

過期

除了清理外,在緩存項過期時,ASP.NET 會自動從緩存中移除這些項。向緩存添加項時,可以按下表中的描述設置其過期時間。

 
過期類型 說明

可調過期

指定某項自上次被訪問后多長時間過期。例如,可以將某項設置為自上次在緩存中被訪問后 20 分鍾過期。

絕對過期

指定某項在設定的時間過期,而不考慮訪問頻率。例如,可以將某項設置為在 6:00 PM 過期,或四小時后過期。

依賴項

可以將緩存中某一項的生存期配置為依賴於其他應用程序元素,如某個文件或數據庫。當緩存項依賴的元素更改時,ASP.NET 將從緩存中移除該項。例如,如果您的網站顯示一份報告,該報告是應用程序通過 XML 文件創建的,您可以將該報告放置在緩存中,並將其配置為依賴於該 XML 文件。當 XML 文件更改時,ASP.NET 會從緩存中移除該報告。當代碼請求該報告時,代碼會先確定該報告是否在緩存中,如果不在,代碼會重新創建該報告。因此,始終都有最新版本的報告可用。

ASP.NET 緩存支持下表中描述的依賴項。

 
依賴項 說明

鍵依賴項

應用程序緩存中的項存儲在鍵/值對中。鍵依賴項允許項依賴於應用程序緩存中另一項的鍵。如果移除了原始項,則具有鍵依賴關系的項也會被移除。例如,可以添加一個名為 ReportsValid 的緩存項,然后緩存若干個依賴於 ReportsValid 鍵的報告。當 ReportsValid 項被移除時,所有依賴於它的緩存報告同樣也會從緩存中移除。

文件依賴項

緩存中的項依賴於外部文件。如果該文件被修改或刪除,則緩存項也會被移除。

SQL 依賴項

緩存中的項依賴於 Microsoft SQL Server 2005、SQL Server 2000 或 SQL Server 7.0 數據庫中表的更改。對於 SQL Server 2005,緩存中的項可依賴於表中的某一行。有關更多信息,請參見使用 SqlCacheDependency 類在 ASP.NET 中緩存

聚合依賴項

通過使用 AggregateCacheDependency 類緩存中的項依賴於多個元素。如果任何依賴項發生更改,該項都會從緩存中移除。

自定義依賴項

可以用您自己的代碼創建的依賴關系來配置緩存中的項。例如,可以創建一個自定義 Web 服務緩存依賴項,當調用 Web 服務得到一個特定值時,該依賴項就會從緩存中移除數據。

應用程序緩存項移除通知

當項從應用程序緩存中移除時,您可以收到通知。例如,如果有一個需要大量處理時間才能創建的項,當從緩存中移除該項時,您會收到通知以便可以立即替換該項。這樣,下次請求該項時,用戶便不必等待處理該項。有關更多信息,請參見如何:從緩存中移除項時通知應用程序

ASP.NET 緩存中的新增功能 

 

ASP.NET 2.0 版保留了 ASP.NET 1.1 版的所有緩存功能,同時添加了新功能並增強了現有功能。新功能包括緩存配置文件、自定義緩存依賴項、SQL 緩存依賴項以及在緩存頁中創建動態內容(緩存后替換)。增強功能包括功能更強大的部分頁(控件)緩存模型、增強的緩存配置以及輸出緩存指令的改進。

新緩存功能

緩存配置文件

緩存配置文件使您能夠在應用程序的 Web.config 文件中創建緩存設置,然后在單個頁上引用這些設置。這使您能夠將緩存設置同時應用於多頁。例如,可以定義一個名為 DailyUpdate 的緩存配置文件,它將頁的緩存持續時間設置為一天。然后可以配置各個頁使用 DailyUpdate 緩存配置文件,並且這些頁的緩存持續時間為一天。如果將 DailyUpdate 緩存配置文件更改為不使用緩存,將停止緩存這些頁。有關更多信息,請參見 ASP.NET 中的緩存配置

自定義緩存依賴項

在 ASP.NET 2.0 中,您可以根據應用程序特定情況創建自己的自定義緩存依賴項。若要創建自定義緩存依賴項,請創建從 CacheDependency 繼承的類並在自定義類中實現您自己的依賴項方法。例如,您可以創建在 Web 服務中輪詢數據的依賴項;當數據發生變化時,您可以使緩存數據無效。若要了解通過指定依賴項向緩存添加項目的信息,請參見如何:將項添加到緩存中

SqlCacheDependency

ASP.NET 2.0 引入了 SqlCacheDependency 類,它使您能夠在緩存中配置一個項,以便在 Microsoft SQL Server 數據庫中的表或行上擁有依賴項。當表中或特定行中發生更改時,具有依賴項的緩存項便會失效並從緩存中移除。ASP.NET 2.0 使您能夠在 SQL Server 7.0、SQL Server 2000 和 SQL Server 2005 中設置表的依賴項。使用 SQL Server 2005 時,您還可以設置特定記錄的依賴項。有關更多信息,請參見使用 SqlCacheDependency 類在 ASP.NET 中緩存

緩存后替換

ASP.NET 2.0 現在支持緩存后替換,使您能夠將頁中的某一部分配置為不可緩存。因此,盡管緩存了該頁,但在再次請求該頁時,將重新處理它的部分內容。例如,您可以使用大多數靜態內容(但不能使用在Label 控件中顯示用戶名的內容)創建緩存頁。如果不使用緩存后替換,用戶名在所有請求中保持不變。如果使用緩存后替換,您可以將頁標記為可緩存,然后將 Label 控件放置在標記為不可緩存的另一個控件中。此后每次請求該頁時,都會刷新用戶名。有關更多信息,請參見緩存 ASP.NET 頁的某些部分

緩存增強

控件緩存

在 ASP.NET 1.1 中,通過設置 @ Control 指令中的參數以聲明方式配置用戶控件緩存。在 ASP.NET 2.0 中,可以在運行時使用 CachePolicy 對象配置用戶控件緩存設置。CachePolicy 對象使您能夠按照以編程方式處理頁輸出緩存的相同方式處理用戶控件緩存。有關更多信息,請參見緩存 ASP.NET 頁的某些部分

緩存配置增強

除了緩存配置文件外,ASP.NET 2.0 中還引入了新的緩存配置設置,可以在應用程序的 Web.config 文件中指定這些設置。這些設置增加了您對緩存的控制,如內存使用量和緩存清理行為。有關更多信息,請參見 ASP.NET 中的緩存配置

輸出緩存指令改進

ASP.NET 2.0 包括新的 @ OutputCache 指令選項以及對現有選項的增強。新功能和增強功能使您能夠對輸出緩存功能進行聲明控制,而以前只能使用 HttpCachePolicy 類以編程方式實現此類控制。例如,現在可以用聲明方式設置頁 @ OutputCache 指令中的 Duration 屬性和 NoStore 屬性。有關更多信息,請參見設置頁的可緩存性

緩存應用程序數據 

 

ASP.NET 為您提供了一個強大的、便於使用的緩存機制,用於將需要大量服務器資源來創建的對象存儲在內存中。緩存這些類型的資源會大大改進應用程序的性能。

緩存是由 Cache 類實現的;緩存實例是每個應用程序專用的。緩存生存期依賴於應用程序的生存期;重新啟動應用程序后,將重新創建 Cache 對象。

設計 Cache 類是為了便於使用。您可以將項放置在 Cache 中,並在以后使用簡單的鍵/值對來檢索這些項。有關如何執行此操作的示例,請參見如何:將項添加到緩存中如何:檢索緩存項的值

Cache 類提供了強大的功能,允許您自定義如何緩存項以及將它們緩存多長時間。例如,當缺乏系統內存時,緩存會自動移除很少使用的或優先級較低的項以釋放內存。該技術也稱為清理,這是緩存確保過期數據不使用寶貴的服務器資源的方式之一。

當執行清理時,您可以指示 Cache 給予某些項比其他項更高的優先級。若要指示項的重要性,可以在使用 Add 或 Insert 方法添加項時指定一個 CacheItemPriority 枚舉值。

當使用 Add 或 Insert 方法將項添加到緩存時,您還可以建立項的過期策略。您可以通過使用DateTime 值指定項的確切過期時間(絕對過期時間),來定義項的生存期。也可以使用 TimeSpan 值指定一個彈性過期時間,彈性過期時間允許您根據項的上次訪問時間來指定該項過期之前的運行時間。一旦項過期,便將它從緩存中移除。試圖檢索它的值的行為將返回 null(在 Visual Basic 中為Nothing),除非該項被重新添加到緩存中。

對於存儲在緩存中的易失項(例如那些定期進行數據刷新的項或那些只在一段時間內有效的項),通常設置一種過期策略:只要這些項的數據保持為最新的,就將它們保留在緩存中。例如,如果您正在編寫一個應用程序,該應用程序通過另一個網站獲取數據來跟蹤體育比賽的比分,那么只要源網站上比賽的比分不更改,就可以緩存這些比分。在此情況下,您可以根據其他網站更新比分的頻率來設置過期策略。您可以編寫代碼來確定緩存中是否是最新的比分。如果該比分不是最新的,則代碼可以從源網站讀取比分並緩存新值。

最后,ASP.NET 允許您根據外部文件、目錄(文件依賴項)或另一個緩存項(鍵依賴項)來定義緩存項的有效性。如果具有關聯依賴項的項發生更改,緩存項便會失效並從緩存中移除。您可以使用該技術在項的數據源更改時從緩存中移除這些項。例如,如果您編寫一個處理 XML 文件中的財務數據的應用程序,則可以從該文件將數據插入緩存中並在此 XML 文件上保留一個依賴項。當該文件更新時,從緩存中移除該項,您的應用程序重新讀取 XML 文件,然后將刷新后的數據放入緩存中。

Note注意

Cache 對象沒有關於它所包含項的內容的信息。它只保留對這些對象的引用。它還提供跟蹤它們的依賴項和設置到期策略的方法。

ASP.NET 中的緩存配置 

 

ASP.NET 提供了許多可用於配置頁面輸出緩存和緩存 API 的選項。可以在處理了頁面響應后使用頁面輸出緩存來緩存此頁面響應。也可以通過編程的方式使用緩存 API 來緩存應用程序數據。有關更多信息,請參見 ASP.NET 緩存概述

頁面輸出緩存配置

您可以在以下這些位置配置頁面輸出緩存:

  • 配置文件 可以在應用程序配置層次結構的任何配置文件中配置頁面輸出緩存設置,包括 Machine.config 文件(用於設置計算機上所有的 Web 應用程序)和特定於應用程序的 Web.config 文件(用於設置單個應用程序)。

  • 單個頁面 可以在單個頁面中以聲明方式或編程方式設置緩存選項。還可將在配置文件中創建的緩存配置文件應用於單個頁面。

  • 用戶控件 可以在單個用戶控件中以聲明方式或編程方式設置緩存。對於在其他情況下不緩存的頁面內容來說,這是一種簡便的緩存方法。

Web.config 緩存配置設置

在 Web.config 文件中,有兩個頂級配置節可用於頁輸出緩存:OutputCacheSection 和OutputCacheSettingsSection

OutputCacheSection 節用於配置應用程序范圍的設置,例如是啟用還是禁用頁輸出緩存。例如,您可以通過向 Web.config 文件中的 OutputCacheSection 添加 enableOutputCache="false" 來對整個應用程序禁用頁輸出緩存。由於配置文件中的設置要優先於單個頁面中的緩存設置,因此,示例設置將導致不使用輸出緩存。

OutputCacheSettingsSection 用於配置可由單個頁使用的配置文件和依賴項。例如,下面的代碼創建了一個名為 CacheProfile1 的 OutputCacheProfile,它將緩存實現頁 60 秒:

 
<outputCacheSettings>
  <outputCacheProfiles>
    <add name="CacheProfile1" duration="60" />
  </outputCacheProfiles>
</outputCacheSettings>

Machine.config 緩存配置設置

Machine.config 文件的配置節與 Web.config 文件的配置節基本相同,而只有一點區別:即可以鎖定 Machine.config 文件中的配置設置,使任何級別的單個應用程序都無法重寫這些配置設置。在宿主不希望單個應用程序修改緩存配置時,可能有必要在共享宿主方案中使用此功能。有關更多信息,請參見如何:鎖定 ASP.NET 配置設置

頁面緩存配置設置

通過應用在配置文件中定義的緩存配置文件,可以配置單個頁中的緩存。也可以在 @ OutputCache 指令中配置單個緩存屬性 (property),或者通過設置頁的類定義中的屬性 (attribute) 進行配置。有關更多信息,請參見 @ OutputCache 和設置頁的可緩存性

用戶控件緩存配置設置

通過設置用戶控件文件中的 @ OutputCache 指令,或設置控件類定義中的 PartialCachingAttribute屬性,可以對用戶控件緩存進行配置。有關更多信息,請參見緩存 ASP.NET 頁的某些部分

緩存 API 配置設置

可以在 Web.config 文件中配置應用程序的緩存 API。對於頁面輸出緩存,應用程序宿主可以在 Machine.config 文件中設置配置屬性,並鎖定所有應用程序的緩存配置設置。應用程序緩存 API 在CacheSection 中進行配置。例如,您可以使用下面的配置元素來禁用項過期:

<cache disableExpiration="true" />

還可以通過為屬性(如配置文件的 CacheSection 中的 DisableExpiration 和DisableMemoryCollection 屬性)賦值的方式來指定其他應用程序緩存 API 配置設置。


如何:將項添加到緩存中 

 

可以使用 Cache 對象訪問應用程序緩存中的項。可以使用 Cache 對象的 Insert 方法向應用程序緩存添加項。該方法向緩存添加項,並且通過幾次重載,您可以用不同選項添加項,以設置依賴項、過期和移除通知。如果使用 Insert 方法向緩存添加項,並且已經存在與現有項同名的項,則緩存中的現有項將被替換。

還可以使用 Add 方法向緩存添加項。使用此方法,您可以設置與 Insert 方法相同的所有選項;然而,Add 方法將返回您添加到緩存中的對象。另外,如果使用 Add 方法,並且緩存中已經存在與現有項同名的項,則該方法不會替換該項,並且不會引發異常。

本主題中的過程闡釋了向應用程序緩存添加項的如下方式:

  • 通過鍵和值直接設置項,向緩存添加項。

  • 使用 Insert 方法向緩存添加項。

  • 向緩存添加項並添加依賴項,以便當該依賴項更改時,將該項從緩存中移除。可以基於其他緩存項、文件和多個對象設置依賴項。

  • 將設有過期策略的項添加到緩存中。除了能設置項的依賴項以外,還可以設置項在一段時間以后(彈性過期)或在指定時間(絕對過期)過期。您可以定義絕對過期時間或彈性過期時間,但不能同時定義兩者。

  • 向緩存添加項,並定義緩存的項的相對優先級。相對優先級幫助 .NET Framework 確定要移除的緩存項;較低優先級的項比較高優先級的項先從緩存中移除。

  • 通過調用 Add 方法添加項。

除了這里顯示的依賴項,可以在 SQL Server 表上或基於自定義依賴項創建依賴項。有關更多信息,請參見 ASP.NET 緩存概述使用 SqlCacheDependency 類在 ASP.NET 中緩存

當從緩存中移除項時,還可以使用 CacheItemRemovedCallback 委托讓應用程序緩存通知應用程序。有關完整示例,請參見如何:從緩存中移除項時通知應用程序

通過鍵和值直接設置項向緩存添加項

  • 通過指定項的鍵和值,像將項添加到字典中一樣將其添加到緩存中。

    下面的代碼示例將名為 CacheItem1 的項添加到 Cache 對象中:

    Cache["CacheItem1"] = "Cached Item 1";
    

     

    Visual Basic
    Cache("CacheItem1") = "Cached Item 1"
    

通過使用 Insert 方法將項添加到緩存中

  • 調用 Insert 方法,傳遞要添加的項的鍵和值。

    下面的代碼示例添加名為 CacheItem2 的字符串:

    Cache.Insert("CacheItem2", "Cached Item 2");
    

     

    Visual Basic
    Cache.Insert("CacheItem2", "Cached Item 2")
    

通過指定依賴項向緩存添加項

  • 調用 Insert 方法,將 CacheDependency 對象的一個實例傳遞給該方法

    下面的代碼示例添加名為 CacheItem3 的項,該項依賴於緩存中名為 CacheItem2 的另一個項:

    string[] dependencies = { "CacheItem2" };
    Cache.Insert("CacheItem3", "Cached Item 3",
        new System.Web.Caching.CacheDependency(null, dependencies));
    

     

    Visual Basic
    Dim dependencies As String() = {"CacheItem2"}
    Cache.Insert("CacheItem3", "Cached Item 3", _
        New System.Web.Caching.CacheDependency( _
        Nothing, dependencies))
    

    下面的代碼示例演示將名為 CacheItem4 的項添加到緩存中,並且在名為 XMLFile.xml 的文件上設置文件依賴項:

    Cache.Insert("CacheItem4", "Cached Item 4",
        new System.Web.Caching.CacheDependency(
        Server.MapPath("XMLFile.xml")));
    

     

    Visual Basic
    Cache.Insert("CacheItem4", "Cached Item 4", _
        New System.Web.Caching.CacheDependency( _
        Server.MapPath("XMLFile.xml")))
    

    下面的代碼示例演示如何創建多個依賴項。它向緩存中名為 CacheItem1 的另一個項添加鍵依賴項,向名為 XMLFile.xml 的文件添加文件依賴項。

    System.Web.Caching.CacheDependency dep1 = 
        new System.Web.Caching.CacheDependency(Server.MapPath("XMLFile.xml"));
    string[] keyDependencies2 = { "CacheItem1" };
    System.Web.Caching.CacheDependency dep2 = 
        new System.Web.Caching.CacheDependency(null, keyDependencies2);
    System.Web.Caching.AggregateCacheDependency aggDep = 
        new System.Web.Caching.AggregateCacheDependency();
    aggDep.Add(dep1);
    aggDep.Add(dep2);
    Cache.Insert("CacheItem5", "Cached Item 5", aggDep);
    

     

    Visual Basic
    Dim dep1 As CacheDependency = _
        New CacheDependency(Server.MapPath("XMLFile.xml"))
    Dim keyDependencies2 As String() = {"CacheItem1"}
    Dim dep2 As CacheDependency = _
        New System.Web.Caching.CacheDependency(Nothing, _
        keyDependencies2)
    Dim aggDep As AggregateCacheDependency = _
        New System.Web.Caching.AggregateCacheDependency()
    aggDep.Add(dep1)
    aggDep.Add(dep2)
    Cache.Insert("CacheItem5", "Cached Item 5", aggDep)
    

將設有過期策略的項添加到緩存中

  • 調用 Insert 方法,將絕對過期時間或彈性過期時間傳遞給該方法。

    下面的代碼示例將有一分鍾絕對過期時間的項添加到緩存中:

    Cache.Insert("CacheItem6", "Cached Item 6",
        null, DateTime.Now.AddMinutes(1d), 
        System.Web.Caching.Cache.NoSlidingExpiration);
    

     

    Visual Basic
    Cache.Insert("CacheItem6", "Cached Item 6", _
        Nothing, DateTime.Now.AddMinutes(1.0), _
        TimeSpan.Zero)
    

    下面的代碼示例將有 10 分鍾彈性過期時間的項添加到緩存中:

    Cache.Insert("CacheItem7", "Cached Item 7",
        null, System.Web.Caching.Cache.NoAbsoluteExpiration,
        new TimeSpan(0, 10, 0));
    

     

    Visual Basic
    Cache.Insert("CacheItem7", "Cached Item 7", _
        Nothing, System.Web.Caching.Cache.NoAbsoluteExpiration, _
        New TimeSpan(0, 10, 0))
    

將設有優先級設置的項添加到緩存中

  • 調用 Insert 方法,從 CacheItemPriority 枚舉中指定一個值。

    下面的代碼示例將優先級值為 High 的項添加到緩存中:

    Cache.Insert("CacheItem8", "Cached Item 8",
        null, System.Web.Caching.Cache.NoAbsoluteExpiration,
        System.Web.Caching.Cache.NoSlidingExpiration,
        System.Web.Caching.CacheItemPriority.High, null);
    

     

    Visual Basic
    Cache.Insert("CacheItem8", "Cached Item 8", _
        Nothing, System.Web.Caching.Cache.NoAbsoluteExpiration, _
        System.Web.Caching.Cache.NoSlidingExpiration, _
        System.Web.Caching.CacheItemPriority.High, _
        Nothing)  
    

使用 Add 方法向緩存添加項

  • 調用 Add 方法,它返回一個表示項的對象。

    下面的代碼示例向緩存添加名為 CacheItem9 的項,同時將變量 CachedItem9 的值設置為已添加的項。

    string CachedItem9 = (string)Cache.Add("CacheItem9",
        "Cached Item 9", null,
        System.Web.Caching.Cache.NoAbsoluteExpiration,
        System.Web.Caching.Cache.NoSlidingExpiration, 
        System.Web.Caching.CacheItemPriority.Default,
        null);
    

     

    Visual Basic
    Dim CachedItem9 As String = CStr(Cache.Add("CacheItem9", _
        "Cached Item 9", Nothing, _
        System.Web.Caching.Cache.NoAbsoluteExpiration, _
        System.Web.Caching.Cache.NoSlidingExpiration, _
        System.Web.Caching.CacheItemPriority.Default, _
        Nothing))
    
如何:檢索緩存項的值 

 

要從緩存中檢索數據,應指定存儲緩存項的鍵。不過,由於緩存中所存儲的信息為易失信息,即該信息可能由 ASP.NET 移除,因此建議的開發模式是首先確定該項是否在緩存中。如果不在,則應將它重新添加到緩存中,然后檢索該項。

檢索緩存項的值

  • 通過在 Cache 對象中進行檢查來確定該項是否不為 null(在 Visual Basic 中為 Nothing)。如果該項存在,則將它分配給變量。否則,重新創建該項,將它添加到緩存中,然后訪問它。

    下面的代碼示例演示如何從緩存中檢索名為 CacheItem 的項。代碼將該項的內容分配給名為 cachedString 的變量。如果該項不在緩存中,則代碼會將它添加到緩存中,然后將它分配給 cachedString

    string cachedString;
    cachedString = (string)Cache["CacheItem"];
    if (cachedString == null)
    {
      cachedString = "Hello, World.";
      Cache.Insert("CacheItem", cachedString);
    }
    

     

    Visual Basic
    Dim cachedString As String
    cachedString = CStr(Cache("CacheItem"))
    If cachedString Is Nothing Then
      cachedString = "Hello, World."
      Cache.Insert("CacheItem", cachedString)
    End If
    
如何:從緩存中移除項時通知應用程序 

 

在大多數緩存方案中,當從緩存中移除項后,直到再次需要此項時,才需要將其放回緩存中。典型的開發模式是在使用項之前始終檢查該項是否已在緩存中。如果項位於緩存中,則可以使用。如果不在緩存中,則應再次檢索該項,然后將其添加回緩存。

但是,在某些情況下,如果從緩存中移除項時通知應用程序,可能非常有用。例如,您可能具有一個緩存的報告,創建該報告需花費大量的時間進行處理。當該報告從緩存中移除時,您希望重新生成該報告,並立即將其置於緩存中,以便下次請求該報告時,用戶不必等待對此報告進行處理。

為了在從緩存中移除項時能夠發出通知,ASP.NET 提供了 CacheItemRemovedCallback 委托。該委托定義編寫事件處理程序時使用的簽名,當對從緩存中移除項進行響應時會調用此事件處理程序。ASP.NET 還提供 CacheItemRemovedReason 枚舉,用於指定移除緩存項的原因。

通常,通過在管理嘗試檢索的特定緩存數據的業務對象中創建處理程序,來實現回調。例如,您可能有一個 ReportManager 對象,該對象具有兩種方法,即 GetReportCacheReportGetReport 報告方法檢查緩存以查看報告是否已緩存;如果沒有,該方法將重新生成報告並將其緩存。CacheReport 方法具有與 CacheItemRemovedCallback 委托相同的函數簽名;從緩存中移除報告時,ASP.NET 會調用 CacheReport 方法,然后將報告重新添加到緩存中。

當從緩存中移除項時通知應用程序

  1. 創建一個類,負責從緩存中檢索項並處理回調方法,以將項添加回緩存中。

  2. 在該類中,創建用於將項添加到緩存中的方法。

  3. 在該類中,創建用於從緩存中獲取項的方法。

  4. 創建用於處理緩存項移除回調的方法。該方法必須具備與 CacheItemRemovedCallback 委托相同的函數簽名。從緩存中刪除項時,會在該方法中執行要運行的邏輯,如重新生成項並將其添加回緩存中。

測試緩存項回調

  1. 創建一個 ASP.NET 網頁,該網頁將調用類中用於將項添加到緩存中的方法。

    下面的代碼示例演示如何調用 ReportManager 類的 GetReport 方法(在此過程后面的示例中定義)。然后將在使用頁面的 Page_Load 方法期間顯示 Label 控件 Label1 中的報告。

    protected void Page_Load(object sender, EventArgs e)
    {
        this.Label1.Text = ReportManager.GetReport();
    }
    

     

    Visual Basic
    Protected Sub Page_Load(ByVal sender As Object, _
            ByVal e As System.EventArgs) Handles Me.Load
        Me.Label1.Text = ReportManager.GetReport()
    End Sub
    
  2. 在瀏覽器中請求 ASP.NET 頁並查看報告。

    報告是在首次請求頁時創建的,在緩存中的報告被移除之前,后續請求都將訪問緩存中的報告。

示例

下面的代碼示例演示一個名為 ReportManager 的、用於在從緩存中刪除項時處理通知的完整類。該類管理字符串形式的報告,此報告表示一個長期運行的進程。

盡管該示例使用聲明為 static(在 Visual Basic 中為 Shared)的類,但並不是必須使用靜態類。不過,刪除緩存項時,用於處理回調的方法必須存在。例如,不應在 ASP.NET 頁中實現回調處理程序,因為在從緩存中刪除項之前該頁可能已被釋放,因此用於處理回調的方法將不可用。為了確保從緩存中刪除項時處理回調的方法仍然存在,請使用該方法的靜態類。但是,靜態類的缺點是需要保證所有靜態方法都是線程安全的。

Caution note警告

請不要在頁面中將 CacheItemRemovedCallback 設置為一個方法。除了在釋放頁面后回調無法使用頁面方法以外,將回調指向頁面方法還會阻礙垃圾回收將頁面使用的內存回收。由於回調包含對頁面的引用,而垃圾回收器不會從內存中移除包含任何引用的項,因此會出現這種情況。在加載應用程序期間,這可能會導致內存很快被用光。

該示例類包括以下功能:

  • 私有成員,用於跟蹤報告是否已從緩存中移除。

  • 名為 CacheReport 的方法,用於將項以 MyReport 的名稱添加到緩存中,並將該項設置為在添加到緩存中后一分鍾過期。該方法還會將 ReportRemovedCallback 方法傳遞給 onRemoveCallback 參數,從而注冊 ReportRemoveCallback 方法,以便在從緩存中刪除項時進行調用。

  • 名為 GetReport 的方法,用於從緩存中獲取項。該方法確定名為 MyReport 的項是否存在於緩存中。如果該項不存在,則該方法將調用 CacheReport,,將該項添加到緩存中。

  • 名為 ReportRemovedCallback 的方法,用於處理緩存項移除回調。ReportRemovedCallback 具有與 CacheItemRemovedCallback 委托相同的函數簽名。該方法將變量 _reportRemovedFromCache 設置為 true,然后通過 CacheReport 方法將項添加回緩存中。

using System;
using System.Web;
using System.Web.Caching;
public static class ReportManager
{
    private static bool _reportRemovedFromCache = false;
    static ReportManager()
    { }

    public static String GetReport()
    {
        lock (typeof(ReportManager))
        {
            if (HttpContext.Current.Cache["MyReport"] != null)
                return (string)HttpRuntime.Cache["MyReport"];
            else
            {
                CacheReport();
                return (string)HttpRuntime.Cache["MyReport"];
            }
        }
    }

    public static void CacheReport()
    {
        lock (typeof(ReportManager))
        {
            HttpContext.Current.Cache.Add("MyReport",
                CreateReport(), null, DateTime.MaxValue,
                new TimeSpan(0, 1, 0), 
                System.Web.Caching.CacheItemPriority.Default,
                ReportRemovedCallback);
        }
    }

    private static string CreateReport()
    {
        System.Text.StringBuilder myReport = 
            new System.Text.StringBuilder();
        myReport.Append("Sales Report<br />");
        myReport.Append("2005 Q2 Figures<br />");
        myReport.Append("Sales NE Region - $2 million<br />");
        myReport.Append("Sales NW Region - $4.5 million<br />");
        myReport.Append("Report Generated: " + DateTime.Now.ToString() 
            + "<br />");
        myReport.Append("Report Removed From Cache: " + 
            _reportRemovedFromCache.ToString());
        return myReport.ToString();
    }

    public static void ReportRemovedCallback(String key, object value, 
        CacheItemRemovedReason removedReason)
    {
        _reportRemovedFromCache = true;
        CacheReport();
    }
}
Visual Basic
Imports System
Imports System.Web
Imports System.Web.Caching
Public Class ReportManager
    Private Shared _reportRemovedFromCache As Boolean = False
    Shared Sub New()
    End Sub

    Private Sub New()
    End Sub

    Public Shared Function GetReport() As String
        SyncLock (GetType(ReportManager))
            If HttpContext.Current.Cache("MyReport") IsNot Nothing Then
                Return CStr(HttpRuntime.Cache("MyReport"))
            Else
                CacheReport()
                Return CStr(HttpRuntime.Cache("MyReport"))
            End If
        End SyncLock
    End Function

    Public Shared Sub CacheReport()
        SyncLock (GetType(ReportManager))
            HttpContext.Current.Cache.Add("MyReport", CreateReport(), _
            Nothing, DateTime.MaxValue, New TimeSpan(0, 1, 0), _
            System.Web.Caching.CacheItemPriority.Default, _
            AddressOf ReportRemovedCallback)
        End SyncLock
    End Sub

    Private Shared Function CreateReport() As String
        Dim myReport As New System.Text.StringBuilder()
        myReport.Append("Sales Report<br />")
        myReport.Append("2005 Q2 Figures<br />")
        myReport.Append("Sales NE Region - $2 million<br />")
        myReport.Append("Sales NW Region - $4.5 million<br />")
        myReport.Append("Report Generated: " & _
            DateTime.Now.ToString() & "<br />")
        myReport.Append("Report Removed From Cache: " _
            & _reportRemovedFromCache.ToString())
        Return myReport.ToString()
    End Function

    Public Shared Sub ReportRemovedCallback(ByVal key As String, _
            ByVal value As Object, ByVal removedReason _
            As CacheItemRemovedReason)
        _reportRemovedFromCache = True
        CacheReport()
    End Sub
End Class

如何:從 ASP.NET 緩存中刪除項 

 

ASP.NET 緩存中的數據是易失的,即不能永久保存。由於以下任一原因,緩存中的數據可能會自動移除:

  • 緩存已滿。

  • 該項已過期。

  • 依賴項發生更改。

有關更多信息,請參見 ASP.NET 緩存概述

從緩存中移除項的具體方法由用於向緩存添加項的代碼確定。有關更多信息,請參見如何:將項添加到緩存中。項從緩存中移除時會向您發出通知。有關更多信息,請參見如何:從緩存中移除項時通知應用程序

除了允許從緩存中自動移除項之外,還可以顯式移除項。

Note注意

如果調用 Insert 方法,並向緩存中添加與現有項同名的項,則將從緩存中刪除該舊項。

從緩存中顯式刪除項

  • 調用 Remove 方法,以傳遞要移除的項的鍵。

    下面的示例演示如何移除鍵為 MyData1 的項。

    Visual Basic
    Cache.Remove("MyData1")
    

     

    Cache.Remove("MyData1");
    
使用 SqlCacheDependency 類在 ASP.NET 中緩存 

 

ASP.NET 允許您使用 SqlCacheDependency 類創建依賴於數據庫中表或行的緩存項。當表中或特定行中發生更改時,帶有依賴項的項便會失效,並會從緩存中移除。可以在 Microsoft SQL Server 7.0、SQL Server 2000 和 SQL Server 2005 中設置表的依賴項。如果您使用 SQL Server 2005,還可以設置特定記錄的依賴項。

在某些方案中,使用帶有 SQL 依賴項的緩存可顯著提高應用程序的性能。例如,假定您正在構建一個從數據庫顯示產品信息的電子商務應用程序。如果不進行緩存,則每當用戶要查看產品時,應用程序都必須從數據庫請求數據。您可以在某一時刻將產品信息緩存一天,由於產品信息已經在內存中,因此可確保較快的響應時間,但是,當產品信息發生變化時,緩存的產品信息就會失去與數據庫中數據的同步,且不同步的時間最長可達一天。

使用 SQL 緩存依賴項可以緩存產品信息,並創建一個數據庫表或行更改的依賴項。當且僅當數據更改時,基於該數據的緩存項便會失效並會從緩存中移除。下次從緩存中請求該項時,如果該項不在緩存中,便可以再次向緩存中添加更新后的版本,並且可確保具有最新的數據。

SQL 緩存依賴項還可用於頁輸出緩存。例如,可以創建一個名為 ViewProduct.aspx 的頁,用於顯示有關特定產品的信息。可以將該頁的緩存策略設置為 SQL 依賴項,就如為手動添加到緩存中的項所設置的依賴項一樣。該頁便會一直存儲在緩存中,直至所依賴的表或行發生更改為止。當數據發生更改時,便會重新創建頁,並將新創建的頁再次存儲在輸出緩存中。

有關更多信息,請參見 ASP.NET 緩存概述

功能

ASP.NET SQL 緩存依賴項提供以下功能:

  • SQL 緩存依賴項可用於應用程序緩存和頁輸出緩存。

  • 可在 SQL Server 7.0 及更高版本中使用 SQL 緩存依賴項。

  • 可以在網絡園(一台服務器上存在多個處理器)或網絡場(多台服務器運行同一應用程序)中使用 SQL 緩存依賴項。

  • 與 SQL 緩存依賴項關聯的數據庫操作比較簡單,因此不會給服務器帶來很高的處理成本。

  • 在應用程序和 SQL Server 中配置 SQL 緩存依賴項不需要很精深的 SQL 知識。ASP.NET 中包括可以自動執行此配置的工具。另外,還可以使用 SqlCacheDependencyAdmin 類以編程方式配置 SQL 緩存依賴項。

SQL Server 7.0 和 SQL Server 2000 實現

ASP.NET 為 SQL Server 7.0 和 SQL Server 2000 的緩存依賴項實現了一個輪詢模型。ASP.NET 進程內的一個線程會以指定的時間間隔輪詢 SQL Server 數據庫,以確定數據是否已更改。如果數據已更改,緩存依賴項便會失效,並從緩存中移除。可以在 Web.config 文件中以聲明方式指定應用程序中的輪詢間隔,也可以使用 SqlCacheDependency 類以編程方式指定此間隔。

對於 SQL Server 7.0 和 SQL Server 2000,SQL 緩存依賴項僅限於表級別的數據更改。可以將 ASP.NET 配置為輪詢數據庫來確定表中的更改,但不能確定特定行中的更改。

啟用 SQL 緩存

為了在 SQL Server 7.0 和 SQL Server 2000 中使用 SQL 緩存依賴項,必須先將 SQL Server 配置為支持緩存依賴項。ASP.NET 提供了一些實用工具,可用於配置 SQL Server 上的 SQL 緩存,其中包括一個名為 Aspnet_regsql.exe 的工具和 SqlCacheDependencyAdmin 類。有關如何在 SQL Server 上啟用 SQL 緩存依賴項的更多信息,請參見如何:使用緩存鍵依賴項緩存頁輸出

SQL Server 2005 實現

SQL Server 2005 為緩存依賴項實現的模型不同於 SQL Server 7.0 和 SQL Server 2000 中的緩存依賴項模型。在 SQL Server 2005 中,不需要執行任何特殊的配置步驟來啟用 SQL 緩存依賴項。此外,SQL Server 2005 還實現了一種更改通知模型,可以向訂閱了通知的應用程序服務器發送通知,而不是依賴早期版本的 SQL Server 中必需的輪詢模型。

SQL Server 2005 緩存依賴項在接收通知的更改類型方面更具靈活性。SQL Server 2005 監控對特定 SQL 命令的結果集的更改。如果數據庫中發生了將修改該命令的結果集的更改,依賴項便會使緩存的項失效。此功能使得 SQL Server 2005 可以提供行級別的通知。

對用於測試更改的查詢有一些要求。必須提供完全限定的表名,其中包括所有者名稱(例如 dbo.authors)。總之,SQL 2005 通知支持 Select 查詢和存儲過程,支持多個查詢和嵌套查詢,但不支持聚合操作(例如 COUNT(*))。有關 SQL Server 2005 支持哪些查詢以及通知規則的更多信息,請參見“SQL Books Online”(SQL 聯機叢書)中的主題“Creating a Query for Notification”(創建通知查詢)。

在 ASP.NET 應用程序中配置 SQL 緩存

在對 SQL Server 7.0 或 SQL Server 2000 進行了緩存依賴項配置后,或是在 SQL Server 2005 中創建了適當的命令依賴項后,就可以配置您的應用程序來使用 SQL 緩存依賴項,如同配置任何其他緩存依賴項一樣。例如,可以在 Web.config 文件中創建一個緩存配置文件,然后在應使用 SQL 緩存依賴項的每個頁中引用該緩存配置文件。還可以在通過 SqlCacheDependency 類以編程方式啟用 SQL 緩存依賴項后再使用它。有關更多信息,請參見如何:使用緩存鍵依賴項緩存頁輸出


緩存 ASP.NET 頁 

 

ASP.NET 使您可以緩存 ASP.NET 頁所生成的部分響應或所有響應,在 ASP.NET 中將這種技術稱為輸出緩存。可以在發出請求的瀏覽器、響應請求的 Web 服務器以及請求或響應流中任何其他具有緩存功能的設備(如代理服務器)上緩存頁。緩存為您提供了一個強有力的方式來提高 Web 應用程序的性能。緩存功能允許利用緩存滿足對頁的后續請求,這樣就不需要再次運行最初創建該頁的代碼。對站點中訪問最頻繁的頁進行緩存可以充分地提高 Web 服務器的吞吐量(通常以每秒的請求數計算)。

可以在頁或配置文件中以聲明方式或者通過編程方式使用緩存 API 指定緩存設置。有關更多信息,請參見設置頁的可緩存性

可以根據查詢字符串參數值或窗體變量值(控件值)緩存頁。必須通過使用 @ OutputCache 指令的 VaryByParam 屬性,顯式啟用基於這些類型的值的緩存。有關更多信息,請參見緩存頁的多個版本

當用戶請求某一緩存頁時,ASP.NET 根據已經為該頁定義的緩存策略確定其緩存輸出是否仍有效。如果該輸出有效,則將該緩存輸出發送到客戶端,並且不重新處理該頁。ASP.NET 允許您在此驗證檢查期間運行代碼,以便可以編寫用於檢查頁是否有效的自定義邏輯。有關更多信息,請參見如何:檢查緩存頁的有效性

有時,緩存整個頁是不切實際的,因為在每次請求時可能需要更改頁的某些部分。在這些情況下,可以緩存頁的一部分。ASP.NET 提供了只緩存 ASP.NET 頁的幾部分的功能。有關更多信息,請參見緩存 ASP.NET 頁的某些部分


如何:以聲明方式設置 ASP.NET 頁的可緩存性 

 

某頁或用戶控件的可緩存性指某頁能否在其響應生命周期內緩存到某個設備上。這些設備包括發出請求的客戶端(瀏覽器),響應請求的 Web 服務器,以及請求或響應流中任何具有緩存功能的設備(例如代理服務器)。

如果您在設計時知道某頁需要什么樣的可緩存性設置,您可以以聲明方式設置可緩存性。該頁將為所有請求使用相同的可緩存性設置。有關更多信息,請參見設置頁的可緩存性

以聲明方式設置頁的可緩存性

  1. 在頁中包含 @ OutputCache 指令,並定義 DurationVaryByParam 屬性。

  2. @ OutputCache 指令中包含 Location 屬性,並將其值定義為 OutputCacheLocation 枚舉中的下列值之一:AnyClientDownstreamServerServerAndClientNone

    下面的代碼演示如何將頁的可緩存性設置為 60 秒:

     
    <%@ OutputCache Duration="60" VaryByParam="None"%>
    Note注意

    默認設置為 Any。如果未定義 Location 屬性,則可以將頁輸出緩存在與響應有關的所有具有緩存功能的網絡設備上。其中包括請求客戶端、原服務器、以及響應通過的任何代理服務器。

使用緩存配置文件以聲明方式設置頁的可緩存性

  1. 在應用程序的 Web.config 文件中定義緩存配置文件,在配置文件中包括 durationvaryByParam 設置。

    下面的 <caching> 配置元素定義名為 Cache30Seconds 的緩存配置文件,它將在服務器上將頁緩存 30 秒之久。

     
    <caching>
      <outputCacheSettings>
        <outputCacheProfiles>
          <add name="Cache30Seconds" duration="30" 
            varyByParam="none" />
        </outputCacheProfiles>
      </outputCacheSettings>
    </caching>
  2. 在使用配置文件的每個 ASP.NET 頁中包含 @ OutputCache 指令,並將 CacheProfile 屬性設置為 Web.config 文件中定義的緩存配置文件的名稱。

    下面的代碼指定頁應當使用名為 Cache30Seconds 的緩存配置文件:

     
    <%@ OutputCache CacheProfile="Cache30Seconds" %>
 
                                 
如何:以編程方式設置頁的可緩存性 

 

頁或用戶控件的可緩存性指的是某一頁是否能在該頁的響應生命周期內緩存在某個設備上。緩存頁的這些設備包括發出請求的瀏覽器,響應請求的 Web 服務器,以及請求或響應流中任何可執行緩存的設備,如代理服務器。

如果應用程序將根據運行時條件(如讀取請求標頭)確定可緩存性,您可以通過編程方式設置可緩存性。有關更多信息,請參見設置頁的可緩存性

以編程方式設置頁的可緩存性

  • 在頁的代碼中,調用 Response 對象的 Cache 屬性的 SetCacheability 方法。

    下面的代碼將 Cache-Control HTTP 標頭設置為 Public

    Response.Cache.SetCacheability(HttpCacheability.Public);
    
    Response.Cache.SetCacheability(HttpCacheability.Public)
    

    如果將 NoCacheServerAndNoCache 傳遞到 SetCacheability 方法以防止請求的瀏覽器在它自己的歷史記錄文件夾中緩存某一頁,那么任何時候當某個用戶單擊“后退”或“前進”按鈕時,都會請求響應的新版本。通過調用 Cache 屬性的 SetAllowResponseInBrowserHistory 方法,並且為 allow 參數傳遞 true 值,您可以按條件重寫此行為。

    如果將可緩存性設置為除 NoCacheServerAndNoCache 之外的任何值,ASP.NET 將忽略由 SetAllowResponseInBrowserHistory 方法設置的值。


 

如何:設置 ASP.NET 頁緩存的過期時間值 

 

若要導致某一頁添加到輸出緩存中,需要為該頁建立到期策略。這可以通過以聲明方式或編程方式來實現。

以聲明方式為頁設置輸出緩存到期時間

  • @ OutputCache 指令包括在您要緩存其響應的 ASP.NET 頁(.aspx 文件)中。將 Duration 屬性設置為一個正數值,將 VaryByParam 屬性設置為一個值。

    Note注意

    默認情況下,@ OutputCache 指令將 Cache-Control 標頭設置為 Any

    例如,下面的 @ OutputCache 指令將頁的到期時間設置為 60 秒:

     
    <%@ OutputCache Duration="60" VaryByParam="None" %>
    Note注意

    在使用 @ OutputCache 指令時,必須包括一個 VaryByParam 屬性,否則將出現分析器錯誤。如果不希望使用 VaryByParam 屬性提供的功能,請將它的值設置為“None”。有關更多信息,請參見緩存頁的多個版本

以編程方式為頁設置輸出緩存到期時間

  • 在該頁的代碼中,在 Response 對象的 Cache 屬性中設置該頁的到期策略。

    Note注意

    如果以編程方式設置頁的到期時間,則您還必須為緩存的頁設置 Cache-Control 標頭。為此,請調用 SetCacheability 方法並向其傳遞 HttpCacheability 枚舉值 Public

    下面的代碼示例設置與前面過程中的 @ OutputCache 指令相同的緩存策略。

    Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
    Response.Cache.SetCacheability(HttpCacheability.Public);
    Response.Cache.SetValidUntilExpires(true);
    

     

    Visual Basic
    Response.Cache.SetExpires(DateTime.Now.AddSeconds(60))
    Response.Cache.SetCacheability(HttpCacheability.Public)
    Response.Cache.SetValidUntilExpires(True)
    

    當緩存頁到期時,以后對該頁的請求將導致動態生成的響應。會在指定的持續時間內緩存該響應頁。


 

如何:檢查緩存頁的有效性 

 

用戶請求緩存頁時,ASP.NET 根據您在該頁中定義的緩存策略來確定緩存輸出是否仍然有效。如果緩存輸出有效,則將輸出發送到客戶端,並且不重新處理該頁。但是,ASP.NET 提供了使用驗證回調在該驗證檢查期間運行代碼的功能,因此您可以編寫自定義邏輯來檢查該頁是否有效。利用驗證回調,可以使在使用緩存依賴項的正常進程之外的緩存頁無效。

以編程方式檢查緩存頁的有效性

  1. 定義 HttpCacheValidateHandler 類型的事件處理程序,並包括檢查緩存頁響應的有效性的代碼。

    驗證處理程序必須返回下列 HttpValidationStatus 值之一:

    • Invalid   指示緩存頁無效,將從緩存中移除該頁,並且該請求將被作為緩存未命中處理。

    • IgnoreThisRequest   導致將請求視為緩存未命中處理。因此,將重新處理該頁,但不會使緩存頁無效。

    • Valid   指示緩存頁有效。

    下面的代碼示例闡釋名為 ValidateCacheOutput 的驗證處理程序,該處理程序確定查詢字符串變量 status 包含值“invalid”還是“ignore”。如果狀態值為“invalid”,則該方法返回 Invalid,並且使該頁在緩存中無效。如果狀態值為“ignore”,則該方法返回 IgnoreThisRequest,並且該頁仍保留在緩存中,但為該請求生成一個新響應。

    public static void ValidateCacheOutput(HttpContext context, Object data,
            ref HttpValidationStatus status)
    {
        if (context.Request.QueryString["Status"] != null)
        {
            string pageStatus = context.Request.QueryString["Status"];
    
            if (pageStatus == "invalid")
                status = HttpValidationStatus.Invalid;
            else if (pageStatus == "ignore")
                status = HttpValidationStatus.IgnoreThisRequest;
            else
                status = HttpValidationStatus.Valid;
        }
        else
            status = HttpValidationStatus.Valid;
    }
    

     

    Visual Basic
    Public Shared Sub ValidatePage(ByVal context As HttpContext, _
            ByVal data As [Object], ByRef status As HttpValidationStatus)
        If Not (context.Request.QueryString("Status") Is Nothing) Then
            Dim pageStatus As String = context.Request.QueryString("Status")
    
            If pageStatus = "invalid" Then
                status = HttpValidationStatus.Invalid
            ElseIf pageStatus = "ignore" Then
                status = HttpValidationStatus.IgnoreThisRequest
            Else
                status = HttpValidationStatus.Valid
            End If
       Else
           status = HttpValidationStatus.Valid
       End If
    End Sub
    
  2. 從其中一個頁生命周期事件(如頁的 Load 事件)中調用 AddValidationCallback 方法,將您在步驟 1 中定義的事件處理程序作為第一個參數傳遞。

    下面的代碼示例將 ValidateCacheOutput 方法設置為驗證處理程序。

    protected void Page_Load(object sender, EventArgs e)
    {
        Response.Cache.AddValidationCallback(
            new HttpCacheValidateHandler(ValidateCacheOutput),
            null);
    }
    

     

    Visual Basic
    Protected Sub Page_Load(ByVal sender As Object, _
        ByVal e As System.EventArgs) Handles Me.Load
    
        Response.Cache.AddValidationCallback( _
            New HttpCacheValidateHandler(AddressOf ValidatePage), Nothing)
    End Sub
    
 
                                       
緩存 ASP.NET 頁的某些部分 

 

有時緩存整個頁是不現實的,因為頁的某些部分可能在每次請求時都需要更改。在這些情況下,只能緩存頁的一部分。執行此操作有兩個選項:控件緩存和緩存后替換。

在控件緩存(也稱為片段緩存)中,可以通過創建用戶控件來包含緩存的內容,然后將用戶控件標記為可緩存來緩存部分頁輸出。該選項允許緩存頁中的特定內容,而在每次都重新創建整個頁。例如,如果創建的頁顯示大量動態內容(如股票信息),但也有某些部分是靜態的(如每周摘要),則可以在用戶控件中創建這些靜態部分並將用戶控件配置為緩存。

緩存后替換與控件緩存正好相反。它對頁進行緩存,但是頁中的某些片段是動態的,因此不會緩存這些片段。例如,如果創建的頁在設定的時間段內完全是靜態的(例如新聞報道頁),可以設置為緩存整個頁。如果為緩存的頁添加旋轉廣告橫幅,則在頁請求之間,廣告橫幅不會變化。然而,使用緩存后替換,可以對頁進行緩存,但可以將特定部分標記為不可緩存。在本例中,將廣告橫幅標記為不可緩存。它們將在每次頁請求時動態創建,並添加到緩存的頁輸出中。有關緩存后替換的更多信息,請參閱動態更新緩存頁的部分

控件緩存

通過創建用戶控件來緩存內容,可以將頁上需要花費寶貴的處理器時間來創建的某些部分(例如數據庫查詢)與頁的其他部分分離開。只需占用很少服務器資源的部分可以在每次請求時動態生成。

在標識了要緩存的頁的部分,並創建了用以包含這些部分中的每個部分的用戶控件后,您必須確定這些用戶控件的緩存策略。您可以使用 @ OutputCache 指令,或者在代碼中使用 PartialCachingAttribute 類,以聲明的方式為用戶控件設置這些策略。

例如,如果在用戶控件文件(.ascx 文件)的頂部包括下面的指令,則該控件的一個版本將在輸出緩存中存儲 120 秒。

 
<%@ OutputCache Duration="120" VaryByParam="None" %>

若要在代碼中設置緩存參數,可以在用戶控件的類聲明中使用一個屬性。例如,如果在類聲明的元數據中包括下面的屬性,則該內容的一個版本將在輸出緩存中存儲 120 秒:

[PartialCaching(120)]
public partial class CachedControl : System.Web.UI.UserControl
{
    // Class Code
}
Visual Basic
<PartialCaching(120)> _
Partial Class CachedControl
    Inherits System.Web.UI.UserControl
    ' Class Code
End Class

有關可在頁輸出中設置的屬性的更多信息,請參閱 @ OutputCache 主題。有關如何開發用戶控件的更多信息,請參見 ASP.NET Web 服務器控件概述

Note注意

由於可在頁上嵌套用戶控件,您還可以嵌套已放置到輸出緩存中的用戶控件。可以為頁和嵌套的用戶控件指定不同的緩存設置。

以編程方式引用緩存的用戶控件

在以聲明的方式創建可緩存的用戶控件時,可以包括一個 ID 屬性,以便以編程方式引用該用戶控件實例。但是,在代碼中引用用戶控件之前,必須驗證在輸出緩存中是否存在該用戶控件。緩存的用戶控件只在首次請求時動態生成;在指定的時間到期之前,從輸出緩存滿足所有的后續請求。確定用戶控件已實例化后,可以從包含頁以編程方式操作該用戶控件。例如,如果通過聲明方式將 SampleUserControlID 分配給用戶控件,則可以使用下面的代碼檢查它是否存在。

protected void Page_Load(object sender, EventArgs e)
{
    if (SampleUserControl != null)
       // Place code manipulating SampleUserControl here.
}
Visual Basic
Protected Sub Page_Load(ByVal sender As Object, _
        ByVal e As System.EventArgs) Handles Me.Load
    If SampleUserControl <> Nothing Then
       ' Place code manipulating SampleUserControl here.
    End If
End Sub

以不同的持續時間緩存頁和用戶控件

可以為頁和頁上的用戶控件設置不同的輸出緩存持續時間值。如果頁的輸出緩存持續時間長於用戶控件的輸出緩存持續時間,則頁的輸出緩存持續時間優先。例如,如果頁的輸出緩存設置為 100 秒,而用戶控件的輸出緩存設置為 50 秒,則包括用戶控件在內的整個頁將在輸出緩存中存儲 100 秒,而與用戶控件較短的時間設置無關。

下面的代碼示例演示了當頁的緩存持續時間長於用戶控件的緩存持續時間時的效果。該頁配置為緩存 100 秒。

<%@ Page language="C#" %>
<%@ Register tagprefix="SampleControl" tagname="Time" src="uc01.ascx" %>
<%@ OutputCache duration="100" varybyparam="none" %>

<SampleControl:Time runat="server" /><br /> <br /> <br />

This page was most recently generated at:<p>

<% DateTime t = DateTime.Now.ToString(); 
    Response.Write(t); %>
Visual Basic
<%@ Page language="VB" %>
<%@ Register tagprefix="SampleControl" tagname="Time" src="uc01.ascx" %>
<%@ OutputCache duration="100" varybyparam="none" %>

<SampleControl:Time runat="server" /><br /> <br /> <br />

This page was most recently generated at:<p>
<% Dim t As DateTime = DateTime.Now.ToString()
Response.Write(t) %>

下面的代碼示例演示了包括在頁中的用戶控件。控件的緩存持續時間設置為 50 秒。

<% @Control language="C#" %>
<% @OutputCache duration="50" varybyparam="none" %>

This user control was most recently generated at:<p>
<% DateTime t = DateTime.Now.ToString(); 
    Response.Write(t); %>
Visual Basic
<% @Control language="VB" %>
<% @OutputCache duration="50" varybyparam="none" %>

This user control was most recently generated at:<p>
<% Dim t As DateTime = DateTime.Now.ToString()
Response.Write(t) %>

不過,如果頁的輸出緩存持續時間比用戶控件的輸出緩存持續時間短,則即使已為某個請求重新生成該頁的其余部分,也將一直緩存用戶控件直到其持續時間到期為止。例如,如果頁的輸出緩存設置為 50 秒,而用戶控件的輸出緩存設置為 100 秒,則頁的其余部分每到期兩次,用戶控件才到期一次。

下面的代碼演示了一個頁的標記,該頁中包含的用戶控件的緩存持續時間長於該頁的緩存持續時間。該頁配置為緩存 50 秒。

<%@ Page language="C#" %>
<%@ Register tagprefix="SampleControl" tagname="Time" src="uc2.ascx" %>
<%@ OutputCache duration="50" varybyparam="none" %>

<SampleControl:Time runat="server" /><br /> <br /> <br />

This page was most recently generated at:<p>
 <% DateTime t = DateTime.Now.ToString(); 
    Response.Write(t); %>
Visual Basic
<%@ Page language="VB" %>
<%@ Register tagprefix="SampleControl" tagname="Time" src="Uc2.ascx" %>
<%@ OutputCache duration="50" varybyparam="none" %>

<SampleControl:Time runat="server" /><br /> <br /> <br />

This page was most recently generated at:<p>
 <% Dim t As DateTime = DateTime.Now.ToString()
Response.Write(t) %>

下面的代碼演示了包括在頁中的用戶控件。控件的緩存持續時間設置為 100 秒。

<% @Control language="C#" %>
<% @OutputCache duration="100" varybyparam="none" %>

This user control was most recently generated at:<p>

<% DateTime t = DateTime.Now.ToString(); 
    Response.Write(t); %>
Visual Basic
<% @Control language="VB" %>
<% @OutputCache duration="100" varybyparam="none" %>

This user control was most recently generated at:<p>
<% Dim t As DateTime = DateTime.Now.ToString()
Response.Write(t) %>


緩存頁的多個版本 

 

有時,您可能希望緩存某頁,但是會基於請求為該頁創建不同的版本。例如,根據查詢字符串中傳遞的值,該頁可能具有不同的輸出。

ASP.NET 允許在輸出緩存中緩存同一頁的多個版本。輸出緩存可能會因下列因素而異:

  • 初始請求 (HTTP GET) 中的查詢字符串。

  • 回發時傳遞的控制值(HTTP POST 值)。

  • 隨請求傳遞的 HTTP 標頭。

  • 發出請求的瀏覽器的主版本號。

  • 該頁中的自定義字符串。在這種情況下,可以在 Global.asax 文件中創建自定義代碼以指定該頁的緩存行為。

可以通過以下兩種方法來緩存頁輸出的多個版本:使用 @ OutputCache 指令的屬性以聲明方式,或者使用 HttpCachePolicy 類的屬性和方法以編程方式。

@ OutputCache 指令包括四個可用來緩存頁輸出的多個版本的屬性:

  • VaryByParam 屬性可用來使緩存輸出因查詢字符串而異。

  • VaryByControl 屬性可用來使緩存輸出因控制值而異。

  • VaryByHeader 屬性可用來使緩存輸出因請求的 HTTP 標頭而異。

  • VaryByCustom 屬性可用來使緩存輸出因瀏覽器類型或您定義的自定義字符串而異。

    Note注意

    您必須在任何 @ OutputCache 指令中包括 VaryByParam 屬性或 VaryByControl 屬性。但是,如果您不需要使緩存輸出因控制值或參數而異,則可以定義值為 NoneVaryByParam

HttpCachePolicy 類提供兩個屬性和一個方法,您可以通過它們以編程方式指定與以聲明方式所能設置的緩存配置相同的緩存配置。使用 VaryByParamsVaryByHeaders 屬性可以分別指定查詢字符串參數和標頭名稱作為緩存策略改變依據。使用 SetVaryByCustom 方法可以定義要作為輸出緩存改變依據的自定義字符串。



如何:使用緩存鍵依賴項緩存頁輸出 

 

有時,當緩存中的某一項被移除時,您可能需要從輸出緩存中移除一頁。例如,您可能使用一頁來顯示放置在應用程序緩存中並供多個頁使用的占用大量進程的報告。當該報告已更改或已從緩存中移除時,您希望將頁輸出也從緩存中移除,因為該報告不再有效。為此,可使緩存的頁輸出依賴於其他緩存項。

Note注意

通過調用 RemoveOutputCacheItem 方法,可顯式移除輸出緩存中的任何頁。可以從 Global.asax 文件、自定義 ASP.NET 服務器控件或頁中執行此操作,具體取決於應用程序的需要。

使緩存的頁輸出依賴於另一緩存項

  1. 在頁中,以聲明方式或編程方式指定緩存設置。有關更多信息,請參見如何:設置 ASP.NET 頁緩存的過期時間值設置頁的可緩存性緩存頁的多個版本

  2. 在頁代碼中調用 AddCacheItemDependency 方法。將創建依賴項的緩存項的名稱作為 cacheKey 參數傳遞。

    下面的代碼示例演示如何在名為 ProcessIntensiveReport 的項上設置依賴項。當此項被修改或移除時,將從緩存中移除頁輸出。

    protected void Page_Load(object sender, EventArgs e)
    {
        Response.AddCacheItemDependency("ProcessIntensiveReport");
    
        // Set additional properties to enable caching.
        Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
        Response.Cache.SetCacheability(HttpCacheability.Public);
        Response.Cache.SetValidUntilExpires(true);
    }
    

     

    Visual Basic
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Response.AddCacheItemDependency("ProcessIntensiveReport")
    
        ' Set additional properties to enable caching.
        Response.Cache.SetExpires(DateTime.Now.AddSeconds(60))
        Response.Cache.SetCacheability(HttpCacheability.Public)
        Response.Cache.SetValidUntilExpires(True)
    End Sub
    
    Note注意

    不能在 ASP.NET 用戶控件中調用 AddCacheItemDependency 方法。不過,在指定 @ OutputCache 指令的任何用戶控件中,都可以創建描述緩存鍵依賴項的 CacheDependency 對象,並將其分配給 UserControl 對象的 Dependency 屬性。




  3.  
如何:使用文件依賴項緩存頁輸出 

 

有時候,您可能需要在文件發生更改時從輸出緩存中移除某一頁。例如,您可能有這樣一頁:該頁從生成 XML 文件作為輸出且占用大量進程的報告中獲取其內容。僅當 XML 文件發生更改時,才需要重新處理該頁。要將重新處理限制為僅在需要的時候進行,可以使頁的緩存策略依賴於單個文件。如有必要,可以使緩存頁依賴於多個文件。

Note注意

通過調用 RemoveOutputCacheItem 方法,可顯式移除輸出緩存中的任何頁。可以從 Global.asax 文件、自定義 ASP.NET 服務器控件或頁中執行此操作,具體取決於應用程序的需要。

使緩存頁輸出依賴於一個文件

  1. 以聲明方式或編程方式指定緩存頁輸出的設置。有關更多信息,請參見如何:設置 ASP.NET 頁緩存的過期時間值設置頁的可緩存性緩存頁的多個版本

  2. 在頁代碼中調用 AddFileDependency 方法。將創建依賴項的文件的路徑作為方法的 filename 參數傳遞。

    下面的代碼示例在 TextFile1.txt 文件上設置一個文件依賴項。當文件發生更改時,將從緩存中移除頁輸出。

    protected void Page_Load(object sender, EventArgs e)
    {
        string fileDependencyPath = Server.MapPath("TextFile1.txt");
        Response.AddFileDependency(fileDependencyPath);
    
        // Set additional properties to enable caching.
        Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
        Response.Cache.SetCacheability(HttpCacheability.Public);
        Response.Cache.SetValidUntilExpires(true);
    }
    

     

    Visual Basic
    Protected Sub Page_Load(ByVal sender As Object, _
            ByVal e As EventArgs) Handles Me.Load
        Dim fileDependencyPath As String = _
            Server.MapPath("TextFile1.txt")
        Response.AddFileDependency(fileDependencyPath)
    
        ' Set additional properties to enable caching.
        Response.Cache.SetExpires(DateTime.Now.AddSeconds(60))
        Response.Cache.SetCacheability(HttpCacheability.Public)
        Response.Cache.SetValidUntilExpires(True)
    End Sub
    
    Note注意

    不能從 ASP.NET 用戶控件使用這些方法。但是,在指定 @ OutputCache 指令的任何用戶控件中,您都可以創建一個文件依賴項,並將其分配給 Dependency 屬性。

使緩存頁輸出依賴於文件組

  1. 以聲明方式或編程方式指定緩存頁輸出的設置。有關更多信息,請參見如何:設置 ASP.NET 頁緩存的過期時間值設置頁的可緩存性緩存頁的多個版本

  2. 在頁代碼中,創建一個包含該頁所要依賴的文件的路徑的 String 數組或 ArrayList

  3. 調用 AddFileDependencies 方法,並將數組作為 filenames 參數傳遞。

    下面的代碼示例創建包含 TextFile1.txt 和 XMLFile1.xml 文件的文件路徑的字符串數組,並使頁輸出依賴於這兩個文件。如果修改了其中任何一個文件,將從緩存中移除頁輸出。

    protected void Page_Load(object sender, EventArgs e)
    {
        string[] fileDependencies;
        string fileDependency1 = Server.MapPath("TextFile1.txt");
        string fileDependency2 = Server.MapPath("XMLFile1.xml");
        fileDependencies = new String[] { fileDependency1, 
            fileDependency2 };
        Response.AddFileDependencies(fileDependencies);
    }
    

     

    Visual Basic
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim fileDependencies() As String
        Dim fileDependency1 As String = Server.MapPath("TextFile1.txt")
        Dim fileDependency2 As String = Server.MapPath("XMLFile1.xml")
        fileDependencies = New String() {fileDependency1, _
            fileDependency2}
        Response.AddFileDependencies(fileDependencies)
    End Sub
Public


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM