永久免费看黄A片无码软件,japanese 在线观看国产,强奷高H猛烈失禁潮喷播放,亚洲成精品自拍

rexian

咨詢電話:023-6276-4481

熱門文章

聯(lián)系方式

電 話:023-6276-4481

郵箱:broiling@qq.com

地址:重慶市南岸區(qū)亞太商谷6幢25-2

當前位置:網(wǎng)站首頁 > 技術(shù)文章 > 細說 ASP.NET Cache 及其高級用法

細說 ASP.NET Cache 及其高級用法

編輯:T.T 發(fā)表時間:2017-09-01 12:32:56
T.T

Cache的基本用途

提到Cache,不得不說說它的主要功能:改善程序性能。
ASP.NET是一種動態(tài)頁面技術(shù),用ASP.NET技術(shù)做出來的網(wǎng)頁幾乎都是動態(tài)的,所謂動態(tài)是指:頁面的內(nèi)容會隨著不同的用戶或者持續(xù)更新的數(shù)據(jù), 而呈現(xiàn)出不同的顯示結(jié)果。既然是動態(tài)的,那么這些動態(tài)的內(nèi)容是從哪里來的呢?我想絕大多數(shù)網(wǎng)站都有自己的數(shù)據(jù)源, 程序通過訪問數(shù)據(jù)源獲取頁面所需的數(shù)據(jù),然后根據(jù)一些業(yè)務規(guī)則的計算處理,最后變成適合頁面展示的內(nèi)容。

由于這種動態(tài)頁面技術(shù)通常需要從數(shù)據(jù)源獲取數(shù)據(jù),并經(jīng)過一些計算邏輯,最終變成一些HTML代碼發(fā)給客戶端顯示。而這些計算過程顯然也是有成本的。 這些處理成本最直接可表現(xiàn)為影響服務器的響應速度,尤其是當數(shù)據(jù)的處理過程變得復雜以及訪問量變大時,會變得比較明顯。 另一方面,有些數(shù)據(jù)并非時刻在發(fā)生變化,如果我們可以將一些變化不頻繁的數(shù)據(jù)的最終計算結(jié)果(包括頁面輸出)緩存起來, 就可以非常明顯地提升程序的性能,緩存的最常見且最重要的用途就體現(xiàn)在這個方面。 這也是為什么一說到性能優(yōu)化時,一般都將緩存擺在第一位的原因。 我今天要說到的ASP.NET Cache也是可以實現(xiàn)這種緩存的一種技術(shù)。 不過,它還有其它的一些功能,有些是其它緩存技術(shù)所沒有的。


回到頂部

Cache的定義

在介紹Cache的用法前,我們先來看一下Cache的定義:(說明:我忽略了一些意義不大的成員) 

ASP.NET為了方便我們訪問Cache,在HttpRuntime類中加了一個靜態(tài)屬性Cache,這樣,我們就可以在任意地方使用Cache的功能。 而且,ASP.NET還給它增加了二個“快捷方式”:Page.Cache, HttpContext.Cache,我們通過這二個對象也可以訪問到HttpRuntime.Cache, 注意:這三者是在訪問同一個對象。Page.Cache訪問了HttpContext.Cache,而HttpContext.Cache又直接訪問HttpRuntime.Cache

回到頂部

Cache常見用法

通常,我們使用Cache時,一般只有二個操作:讀,寫。
要從Cache中獲取一個緩存項,我們可以調(diào)用Cache.Get(key)方法,要將一個對象放入緩存,我們可以調(diào)用Add, Insert方法。 然而,Add, Insert方法都有許多參數(shù),有時我們或許只是想簡單地放入緩存,一切接受默認值,那么還可以調(diào)用它的默認索引器, 我們來看一下這個索引器是如何工作的:

public object this[string key]
{    get    {        return this.Get(key);
    }    set    {        this.Insert(key, value);
    }
}

可以看到:讀緩存,其實是在調(diào)用Get方法,而寫緩存則是在調(diào)用Insert方法的最簡單的那個重載版本。

注意了:Add方法也可以將一個對象放入緩存,這個方法有7個參數(shù),而Insert也有一個簽名類似的重載版本, 它們有著類似的功能:將指定項添加到 System.Web.Caching.Cache 對象,該對象具有依賴項、過期和優(yōu)先級策略以及一個委托(可用于在從 Cache 移除插入項時通知應用程序)。 然而,它們有一點小的區(qū)別:當要加入的緩存項已經(jīng)在Cache中存在時,Insert將會覆蓋原有的緩存項目,而Add則不會修改原有緩存項。

也就是說:如果您希望某個緩存項目一旦放入緩存后,就不要再被修改,那么調(diào)用Add確實可以防止后來的修改操作。 而調(diào)用Insert方法,則永遠會覆蓋已存在項(哪怕以前是調(diào)用Add加入的)。

從另一個角度看,Add的效果更像是 static readonly 的行為,而Insert的效果則像 static 的行為。
注意:我只是說【像】,事實上它們比一般的static成員有著更靈活的用法。

由于緩存項可以讓我們隨時訪問,看起來確實有點static成員的味道,但它們有著更高級的特性,比如: 緩存過期(絕對過期,滑動過期),緩存依賴(依賴文件,依賴其它緩存項),移除優(yōu)先級,緩存移除前后的通知等等。 后面我將會分別介紹這四大類特性。

回到頂部

Cache類的特點

Cache類有一個很難得的優(yōu)點,用MSDN上的說話就是:

此類型是線程安全的。

為什么這是個難得的優(yōu)點呢?因為在.net中,絕大多數(shù)類在實現(xiàn)時,都只是保證靜態(tài)類型的方法是線程安全, 而不考慮實例方法是線程安全。這也算是一條基本的.NET設(shè)計規(guī)范原則。
對于那些類型,MSDN通常會用這樣的話來描述:

此類型的公共靜態(tài)(在 Visual Basic 中為 Shared)成員是線程安全的。但不能保證任何實例成員是線程安全的。

所以,這就意味著我們可以在任何地方讀寫Cache都不用擔心Cache的數(shù)據(jù)在多線程環(huán)境下的數(shù)據(jù)同步問題。 多線程編程中,最復雜的問題就是數(shù)據(jù)的同步問題,而Cache已經(jīng)為我們解決了這些問題。

不過我要提醒您:ASP.NET本身就是一個多線程的編程模型,所有的請求是由線程池的線程來處理的。 通常,我們在多線程環(huán)境中為了解決數(shù)據(jù)同步問題,一般是采用鎖來保證數(shù)據(jù)同步, 自然地,ASP.NET也不例外,它為了解決數(shù)據(jù)的同步問題,內(nèi)部也是采用了鎖。

說到這里,或許有些人會想:既然只一個Cache的靜態(tài)實例,那么這種鎖會不會影響并發(fā)?
答案是肯定的,有鎖肯定會在一定程度上影響并發(fā),這是沒有辦法的事情。
然而,ASP.NET在實現(xiàn)Cache時,會根據(jù)CPU的個數(shù)創(chuàng)建多個緩存容器,盡量可能地減小沖突, 以下就是Cache創(chuàng)建的核心過程:

說明:CacheInternal是個內(nèi)部用的包裝類,Cache的許多操作都要由它來完成。

在上面的代碼中,numSingleCaches的計算過程很重要,如果上面代碼不容易理解,那么請看我下面的示例代碼: 

程序?qū)敵觯?/p>

1,2,4,4,8,8,8,8,16,16,16,16,16,16,16,16,32,32,32,32

CacheMultiple的構(gòu)造函數(shù)如下:

現(xiàn)在您應該明白了吧:CacheSingle其實是ASP.NET內(nèi)部使用的緩存容器,多個CPU時,它會創(chuàng)建多個緩存容器。
在寫入時,它是如何定位這些容器的呢?請繼續(xù)看代碼:

說明:參數(shù)中的hashCode是直接調(diào)用我們傳的key.GetHashCode() ,GetHashCode是由Object類定義的。

所以,從這個角度看,雖然ASP.NET的Cache只有一個HttpRuntime.Cache靜態(tài)成員,但它的內(nèi)部卻可能會包含多個緩存容器, 這種設(shè)計可以在一定程度上減少并發(fā)的影響。

不管如何設(shè)計,在多線程環(huán)境下,共用一個容器,沖突是免不了的。如果您只是希望簡單的緩存一些數(shù)據(jù), 不需要Cache的許多高級特性,那么,可以考慮不用Cache 。 比如:可以創(chuàng)建一個Dictionary或者Hashtable的靜態(tài)實例,它也可以完成一些基本的緩存工作, 不過,我要提醒您:您要自己處理多線程訪問數(shù)據(jù)時的數(shù)據(jù)同步問題。
順便說一句:Hashtable.Synchronized(new Hashtable())也是一個線程安全的集合,如果想簡單點,可以考慮它。

接下來,我們來看一下Cache的高級特性,這些都是Dictionary或者Hashtable不能完成的。

回到頂部

緩存項的過期時間

ASP.NET支持二種緩存項的過期策略:絕對過期和滑動過期。
1. 絕對過期,這個容易理解:就是在緩存放入Cache時,指定一個具體的時間。當時間到達指定的時間的時,緩存項自動從Cache中移除。
2. 滑動過期:某些緩存項,我們可能只希望在有用戶在訪問時,就盡量保留在緩存中,只有當一段時間內(nèi)用戶不再訪問該緩存項時,才移除它, 這樣可以優(yōu)化內(nèi)存的使用,因為這種策略可以保證緩存的內(nèi)容都是【很熱門】的。 操作系統(tǒng)的內(nèi)存以及磁盤的緩存不都是這樣設(shè)計的嗎?而這一非常有用的特性,Cache也為我們準備好了,只要在將緩存項放入緩存時, 指定一個滑動過期時間就可以實現(xiàn)了。

以上二個選項分別對應Add, Insert方法中的DateTime absoluteExpiration, TimeSpan slidingExpiration這二個參數(shù)。
注意:這二個參數(shù)都是成對使用的,但不能同時指定它們?yōu)橐粋€【有效】值,最多只能一個參數(shù)值有效。 當不使用另一個參數(shù)項時,請用Cache類定義二個static readonly字段賦值。

這二個參數(shù)比較簡單,我就不多說了,只說一句:如果都使用Noxxxxx這二個選項,那么緩存項就一直保存在緩存中。(或許也會被移除)


回到頂部

緩存項的依賴關(guān)系 - 依賴其它緩存項

ASP.NET Cache有個很強大的功能,那就是緩存依賴。一個緩存項可以依賴于另一個緩存項。 以下示例代碼創(chuàng)建了二個緩存項,且它們間有依賴關(guān)系。首先請看頁面代碼: 

頁面后臺代碼:

當運行這個示例頁面時,運行結(jié)果如下圖所示, 點擊按鈕【設(shè)置Key1的值】時,將會出現(xiàn)緩存項的內(nèi)容(左圖)。點擊按鈕【設(shè)置Key2的值】時,此時將獲取不到緩存項的內(nèi)容(右圖)。

根據(jù)結(jié)果并分析代碼,我們可以看出,在創(chuàng)建Key1的緩存項時,我們使用了這種緩存依賴關(guān)系:

CacheDependency dep = new CacheDependency(null, new string[] { "key2" });

所以,當我們更新Key2的緩存項時,Key1的緩存就失效了(不存在)。

不要小看了這個示例。的確,僅看這幾行示例代碼,或許它們實在是沒有什么意義。 那么,我就舉個實際的使用場景來說明它的使用價值。

上面這幅圖是我寫的一個小工具。在示意圖中,左下角是一個緩存表CacheTable,它由一個叫Table1BLL的類來維護。 CacheTable的數(shù)據(jù)來源于Table1,由Table1.aspx頁面顯示出來。 同時,ReportA, ReportB的數(shù)據(jù)也主要來源于Table1,由于Table1的訪問幾乎絕大多數(shù)都是讀多寫少,所以,我將Table1的數(shù)據(jù)緩存起來了。 而且,ReportA, ReportB這二個報表采用GDI直接畫出(由報表模塊生成,可認是Table1BLL的上層類),鑒于這二個報表的瀏覽次數(shù)較多且數(shù)據(jù)源是讀多寫少, 因此,這二個報表的輸出結(jié)果,我也將它們緩存起來。

在這個場景中,我們可以想像一下:如果希望在Table1的數(shù)據(jù)發(fā)生修改后,如何讓二個報表的緩存結(jié)果失效?
讓Table1BLL去通知那二個報表模塊,還是Table1BLL去直接刪除二個報表的緩存?
其實,不管是選擇前者還是后者,當以后還需要在Table1的CacheTable上做其它的緩存實現(xiàn)時(可能是其它的新報表), 那么,勢必都要修改Table1BLL,那絕對是個失敗的設(shè)計。 這也算是模塊間耦合的所帶來的惡果。

幸好,ASP.NET Cache支持一種叫做緩存依賴的特性,我們只需要讓Table1BLL公開它緩存CacheTable的KEY就可以了(假設(shè)KEY為 CacheTableKey), 然后,其它的緩存結(jié)果如果要基于CacheTable,設(shè)置一下對【CacheTableKey】的依賴就可以實現(xiàn)這樣的效果: 當CacheTable更新后,被依賴的緩存結(jié)果將會自動清除。這樣就徹底地解決了模塊間的緩存數(shù)據(jù)依賴問題。

回到頂部

緩存項的依賴關(guān)系 - 文件依賴

在上篇博客【在.net中讀寫config文件的各種方法】的結(jié)尾, 我給大家留了一個問題:
我希望在用戶修改了配置文件后,程序能立刻以最新的參數(shù)運行,而且不用重啟網(wǎng)站。
今天我就來回答這個問題,并給出所需的全部實現(xiàn)代碼。

首先,我要說明一點:上次博客的問題,雖然解決方案與Cache的文件依賴有關(guān),但還需與緩存的移除通知配合使用才能完美的解決問題。 為了便于內(nèi)容的安排,我先使用Cache的文件依賴來簡單的實現(xiàn)一個粗糙的版本,在本文的后續(xù)部分再來完善這個實現(xiàn)。

先來看個粗糙的版本。假如我的網(wǎng)站中有這樣一個配置參數(shù)類型: 

我可以將它配置在這樣一個XML文件中:

<?xml version="1.0" encoding="utf-8"?>
<RunOptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <WebSiteUrl>http://www.cnblogs.com/fish-li</WebSiteUrl>
  <UserName>fish li</UserName>
</RunOptions>

再來一個用于顯示運行參數(shù)的頁面: 

下面的代碼就可以實現(xiàn):在XML修改后,瀏覽頁面就能立即看到最新的參數(shù)值: 

注意:這里仍然是在使用CacheDependency,只是我們現(xiàn)在是給它的構(gòu)造函數(shù)的第一個參數(shù)傳遞要依賴的文件名。

在即將結(jié)束對緩存的依賴介紹之前,還要補充二點:
1. CacheDependency還支持【嵌套】,即:CacheDependency的構(gòu)造函數(shù)中支持傳入其它的CacheDependency實例,這樣可以構(gòu)成一種非常復雜的樹狀依賴關(guān)系。
2. 緩存依賴的對象還可以是SQL SERVER,具體可參考SqlCacheDependency

回到頂部

緩存項的移除優(yōu)先級

緩存的做法有很多種,一個靜態(tài)變量也可以稱為是一個緩存。一個靜態(tài)的集合就是一個緩存的容器了。 我想很多人都用Dictionary,List,或者Hashtable做過緩存容器,我們可以使用它們來保存各種數(shù)據(jù),改善程序的性能。 一般情況下,如果我們直接使用這類集合去緩存各類數(shù)據(jù),那么,那些數(shù)據(jù)所占用的內(nèi)存將不會被回收,哪怕它們的使用機會并不是很多。 當緩存數(shù)據(jù)越來越多時,它們所消耗的內(nèi)存自然也會越來越多。那么,能不能在內(nèi)存不充足時,釋放掉一些訪問不頻繁的緩存項呢?

這個問題也確實是個較現(xiàn)實的問題。雖然,使用緩存會使用程序運行更快,但是,我們數(shù)據(jù)會無限大,不可能統(tǒng)統(tǒng)緩存起來, 畢竟,內(nèi)存空間是有限的。因此,我們可以使用前面所說的基于一段時間內(nèi)不再訪問就刪除的策略來解決這個問題。 然而,在我們編碼時,根本不知道我們的程序會運行在什么配置標準的計算機上,因此,根本不可能會對內(nèi)存的大小作出任何假設(shè), 此時,我們可能會希望當緩存占用過多的內(nèi)存時,且當內(nèi)存不夠時,能自動移除一些不太重要的緩存項,這或許也比較有意義。

對于這個需求,在.net framework提供了二種解決辦法,一種是使用WeakReference類,另一種是使用Cache 。 不過,既然我們是在使用ASP.NET,選擇Cache當然會更方便。 在Cache的Add, Insert方法的某些重載版本中,可以指定緩存項的保存優(yōu)先級策略,由參數(shù)CacheItemPriority priority來傳入。 其中,CacheItemPriority是一個枚舉類型,它包含了如下枚舉值: 

說明:當我們調(diào)用Cache的Add, Insert方法時,如果不指定CacheItemPriority選項,最終使用Normal所代表的優(yōu)先級。 如果我們希望將某個可能不太重要的數(shù)據(jù)放入緩存時,可以指定優(yōu)先級為Low或者BelowNormal。 如果想讓緩存項在內(nèi)存不足時,也不會被移除(除非到期或者依賴項有改變),可使用NotRemovable。

顯然,我們可以使用這個特性來控制緩存對內(nèi)存壓力的影響。 其它的緩存方案,如static Collection + WeakReference也較難實現(xiàn)這樣靈活的控制。

回到頂部

緩存項的移除通知

ASP.NET Cache與一些static變量所實現(xiàn)的緩存效果并不相同,它的緩存項是可以根據(jù)一些特定的條件失效的,那些失效的緩存將會從內(nèi)存中移除。 雖然,某些移除條件并不是由我們的代碼直接解發(fā)的,但ASP.NET還是提供一種方法讓我們可以在緩存項在移除時,能通知我們的代碼。

注意哦:ASP.NET Cache支持移除【前】通知 和 移除【后】通知二種通知方式。

我們可以在調(diào)用Add, Insert方法時,通過參數(shù)onRemoveCallback傳遞一個CacheItemRemovedCallback類型的委托,以便在移除指定的緩存項時, 能夠通知我們。這個委托的定義如下: 

委托的各個參數(shù)的含義以及移除原因,在注釋中都有明確的解釋,我也不再重復了。
我想:有很多人知道Cache的Add, Insert方法有這個參數(shù),也知道有這個委托,但是,它們有什么用呢? 在后面的二個小節(jié)中,我將提供二個示例來演示這一強大的功能。

通常,我們會以下面這種方式從Cache中獲取結(jié)果:

RunOptions options = HttpRuntime.Cache[RunOptionsCacheKey] as RunOptions;if( options == null ) {    // 緩存中沒有,則從文件中加載
    // ..................................    HttpRuntime.Cache.Insert(RunOptionsCacheKey, options, dep);
}return options;

這其實也是一個慣用法了:先嘗試從緩存中獲取,如果沒有,則從數(shù)據(jù)源中加載,并再次放入緩存。

為什么會在訪問Cache時返回null呢?答案無非就是二種原因:1. 根本沒有放入Cache,2. 緩存項失效被移除了。
這種寫法本身是沒有問題,可是,如果從數(shù)據(jù)源中加載數(shù)據(jù)的時間較長,情況會怎樣呢?
顯然,會影響后面第一次的訪問請求。您有沒有想過,如果緩存項能一直放在Cache中,那不就可以了嘛。 是的,通常來說,只要您在將一個對象放入Cache時,不指定過期時間,不指定緩存依賴,且設(shè)置為永不移除,那么對象確實會一直在Cache中, 可是,過期時間和緩存依賴也很有用哦。如何能二者兼得呢?

為了解決這個問題,微軟在.net framework的3.5 SP1、3.0 SP1、2.0 SP1版本中,加入了【移除前通知】功能,不過,這個方法僅受Insert支持, 隨之而來的還有一個委托和一個移除原因的枚舉定義: 

注意:CacheItemUpdateReason這個枚舉只有二項。原因請看MSDN的解釋:

與 CacheItemRemovedReason 枚舉不同,此枚舉不包含 Removed 或 Underused 值??筛碌木彺骓検遣豢梢瞥模蚨^不會被 ASP.NET 自動移除,即使需要釋放內(nèi)存也是如此。

再一次提醒:有時我們確實需要緩存失效這個特性,但是,緩存失效后會被移除。 雖然我們可以讓后續(xù)的請求在獲取不到緩存數(shù)據(jù)時,從數(shù)據(jù)源中加載,也可以在CacheItemRemovedCallback回調(diào)委托中, 重新加載緩存數(shù)據(jù)到Cache中,但是在數(shù)據(jù)的加載過程中,Cache并不包含我們所期望的緩存數(shù)據(jù),如果加載時間越長,這種【空缺】效果也會越明顯。 這樣會影響(后續(xù)的)其它請求的訪問。為了保證讓我們所期望的緩存數(shù)據(jù)能夠一直存在于Cahce中,且仍有失效機制,我們可以使用【移除前通知】功能。

回到頂部

巧用緩存項的移除通知 實現(xiàn)【延遲操作】

我看過一些ASP.NET的書,也看過一些人寫的關(guān)于Cache方面的文章,基本上,要么是一帶而過,要么只是舉個毫無實際意義的示例。 可惜啊,這么強大的特性,我很少見到有人把它用起來。

今天,我就舉個有實際意義的示例,再現(xiàn)Cache的強大功能!

我有這樣一個頁面,可以讓用戶調(diào)整(上下移動)某個項目分支記錄的上線順序:

當用戶需要調(diào)整某條記錄的位置時,頁面會彈出一個對話框,要求輸入一個調(diào)整原因,并會發(fā)郵件通知所有相關(guān)人員。

由于界面的限制,一次操作(點擊上下鍵頭)只是將一條記錄移動一個位置,當要對某條記錄執(zhí)行跨越多行移動時,必須進行多次移動。 考慮到操作的方便性以及不受重復郵件的影響,程序需要實現(xiàn)這樣一個需求: 頁面只要求輸入一次原因便可以對一條記錄執(zhí)行多次移動操作,并且不要多次發(fā)重復郵件,而且要求將最后的移動結(jié)果在郵件中發(fā)出來。

這個需求很合理,畢竟誰都希望操作簡單。

那么如何實現(xiàn)這個需求呢?這里要從二個方面來實現(xiàn),首先,在頁面上我們應該要完成這個功能,對一條記錄只彈一次對話框。 由于頁面與服務端的交互全部采用Ajax方式進行(不刷新),狀態(tài)可以采用JS變量來維持,所以這個功能在頁面中是很容易實現(xiàn)。 再來看一下服務端,由于服務端并沒有任何狀態(tài),當然也可以由頁面把它的狀態(tài)傳給服務端,但是,哪次操作是最后一次呢? 顯然,這是無法知道的,最后只能修改需求,如果用戶在2分鐘之內(nèi)不再操作某條記錄時,便將最近一次操作視為最后一次操作。

基于新的需求,程序必須記錄用戶的最近一次操作,以便在2分鐘不操作后,發(fā)出一次郵件,但要包含第一次輸入的原因, 還應包含最后的修改結(jié)果哦。

該怎么實現(xiàn)這個需求呢? 我立即就想到了ASP.NET Cache,因為我了解它,知道它能幫我完成這個功能。下面我來說說在服務端是如何實現(xiàn)的。

整個實現(xiàn)的思路是:
1. 客戶端頁面還是每次將記錄的RowGuid, 調(diào)整方向,調(diào)整原因,這三個參數(shù)發(fā)到服務端。
2. 服務端在處理完順序調(diào)整操作后,將要發(fā)送的郵件信息Insert到Cache中,同時提供slidingExpiration和onRemoveCallback參數(shù)。
3. 在CacheItemRemovedCallback回調(diào)委托中,忽略CacheItemRemovedReason.Removed的通知,如果是其它的通知,則發(fā)郵件。

為了便于理解,我特意為大家準備了一個示例。整個示例由三部分組成:一個頁面,一個JS文件,服務端代碼。先來看頁面代碼: 

頁面的顯示效果如下:

處理頁面中二個按鈕的JS代碼如下: 

說明:在服務端,我使用了我在【用Asp.net寫自己的服務框架】那篇博客中提供的服務框架, 服務端的全部代碼是這個樣子的:(注意代碼中的注釋) 

為了能讓JavaScript能直接調(diào)用C#中的方法,還需要在web.config中加入如下配置:

<httpHandlers>
    <add path="*.fish" verb="*" validate="false" type="MySimpleServiceFramework.AjaxServiceHandler"/>
</httpHandlers>

好了,示例代碼就是這些。如果您有興趣,可以在本文的結(jié)尾處下載這些示例代碼,自己親自感受一下利用Cache實現(xiàn)的【延遲處理】的功能。

其實這種【延遲處理】的功能是很有用的,比如還有一種適用場景:有些數(shù)據(jù)記錄可能需要頻繁更新,如果每次更新都去寫數(shù)據(jù)庫,肯定會對數(shù)據(jù)庫造成一定的壓力, 但由于這些數(shù)據(jù)也不是特別重要,因此,我們可以利用這種【延遲處理】來將寫數(shù)據(jù)庫的時機進行合并處理, 最終我們可以實現(xiàn):將多次的寫入變成一次或者少量的寫入操作,我稱這樣效果為:延遲合并寫入

這里我就對數(shù)據(jù)庫的延遲合并寫入提供一個思路:將需要寫入的數(shù)據(jù)記錄放入Cache,調(diào)用Insert方法并提供slidingExpiration和onRemoveCallback參數(shù), 然后在CacheItemRemovedCallback回調(diào)委托中,模仿我前面的示例代碼,將多次變成一次。不過,這樣可能會有一個問題:如果數(shù)據(jù)是一直在修改,那么就一直不會寫入數(shù)據(jù)庫。 最后如果網(wǎng)站重啟了,數(shù)據(jù)可能會丟失。如果擔心這個問題,那么,可以在回調(diào)委托中,遇到CacheItemRemovedReason.Removed時,使用計數(shù)累加的方式,當?shù)竭_一定數(shù)量后, 再寫入數(shù)據(jù)庫。比如:遇到10次CacheItemRemovedReason.Removed我就寫一次數(shù)據(jù)庫,這樣就會將原來需要寫10次的數(shù)據(jù)庫操作變成一次了。 當然了,如果是其它移除原因,寫數(shù)據(jù)庫總是必要的。注意:對于金額這類敏感的數(shù)據(jù),絕對不要使用這種方法。

再補充二點:
1. 當CacheItemRemovedCallback回調(diào)委托被調(diào)用時,緩存項已經(jīng)不在Cache中了。
2. 在CacheItemRemovedCallback回調(diào)委托中,我們還可以將緩存項重新放入緩存。
有沒有想過:這種設(shè)計可以構(gòu)成一個循環(huán)?如果再結(jié)合參數(shù)slidingExpiration便可實現(xiàn)一個定時器的效果。

關(guān)于緩存的失效時間,我要再提醒一點:通過absoluteExpiration, slidingExpiration參數(shù)所傳入的時間,當緩存時間生效時,緩存對象并不會立即移除, ASP.NET Cache大約以20秒的頻率去檢查這些已過時的緩存項。

回到頂部

巧用緩存項的移除通知 實現(xiàn)【自動加載配置文件】

在本文的前部分的【文件依賴】小節(jié)中,有一個示例演示了:當配置文件更新后,頁面可以顯示最新的修改結(jié)果。 在那個示例中,為了簡單,我直接將配置參數(shù)放在Cache中,每次使用時再從Cache中獲取。 如果配置參數(shù)較多