在asp.net中,cache類最酷的特點是它能根據各種依賴來良好的控制自己的行為。以檔案為基礎的依賴是最有用的,檔案依賴項是通過使用cache.insert并提供引用檔案的cachedependency對象添加的
cache.insert("mydata",source,newcachedependency(server.mappath("authors.xml")));
但是當我們想讓緩存根據資料庫的變化而失效的時候,應該怎麼做呢–這種情景在很多應用程式中都存在。asp.net沒有為監視資料庫表的變化提供内在的直接緩存支援。利用sqlserver的不常用的系統存儲過程sp_makewebtask,是可以達到這個目的的,這個存儲過程本來是用作從查詢中生成web頁面的,但是我們隻要稍作修改-在觸發器中使用它,我們就可以取得一個合理有效的途徑,當資料庫某張表的記錄被更新,删除或者修改時來修改某個特定的檔案,這樣會使在cachedependency執行個體中的檔案監視程序偵測到檔案的變化,進而使緩存失效。事實上,因為cachedependency類工作在unc檔案協定上,我們可以在整個webfarm上部署這個解決方案,webfarm上每台機器上的應用程式副本都會通過unc檔案路徑來監視webfarm中某台單個機器上的同一個檔案
廢話少說,讓我們建立一個簡單的web應用程式,來示範它是如果工作的。首先,我們将會使用我們sqlserver中都信賴的northwind範例資料庫。建立一個簡單的datagrid來顯示employees表中的記錄.我們要做的第一件事情就是建立觸發器。
createtriggerwritecachedepfileon[dbo].[employees]
forinsert,update,delete
as
execsp_makewebtask'//peter/c$/cache/mycache.txt','selecttop1firstnamefromemployees'
以上存儲過程就是簡單的告訴sqlserver,如果employee表發生任何變動,就根據一個簡單的查詢來更新”mycache.txt”檔案,有這個簡單的查詢語句其實足夠了,隻要它是一個有效的t-sql語句,sqlserver會很樂意的去更新那個檔案。
接下來,我們需要建立一個目錄,并設為共享。你可能要更新該檔案的通路權限,以使它可以被寫入,注意,我這裡使用的是管理者共享”c$”.另外,你還需要建立一個空的文本檔案,"mycache.txt".
好,現在可以建立我們的應用程式了。首先,在web.config檔案中輸入依賴檔案名稱,這樣做可以使我們在修改依賴檔案的時候不需要重新部署應用程式。
在web.config檔案的根部,添加appsettings配置節:
現在,讓我們在global類中建立緩存機制,這樣我們不需要在任何頁面中編寫特定的代碼
[c#]
publicclassglobal:system.web.httpapplication
{
cache_cache=null;
publicstaticboolblnreflash=false;
publicconststringconnstr="server=localhost;database=northwind;uid=sa;pwd=";
publicconststringstrsql="selectemployeeid,lastname,firstnamefrom
employees";
protectedvoidapplication_start(objectsender,eventargse)
_cache=context.cache;
refreshcahe(null,null,null);
}
protectedvoidsession_start(objectsender,eventargse)
if(httpcontext.current.cache["employees"]==null)
refreshcache(null,null,0);
staticvoidrefreshcache(stringkey,objectitem,cacheitemremovereasonreason)
sqldataadapteradapter=newsqldataadapter(strsql,connstr);
datasetds=newdataset();
adapter.fill(ds,"employees");
cacheitemremovedcallbackonremove=newcacheitemremovedcallback(refreshcache);
stringdepfile=configurationsettings.appsettings["dependencyfile"].tostring();
httpcontext.current.cache.insert("employees",ds,newcachedependency(depfile),
cache.noabsoluteexpiration,cache.noslidingexpiration,
cacheitempriority.high,onremove);
blnreflash=true;
就像上面看到的一樣,我們定義了一個cache類型的_cache對象,在application_start方法中,我們把目前的cache執行個體賦給它,然後調用refreshcache方法去填充該對象。refreshcache實際上是一個靜态的委托回調方法,它所做的就是簡單的從empoyees表中取得一個dataset,然後建立cacheitemremovedcallback類型的委托onremove,使其指向refreshcache方法,這樣當被監控的檔案變化時,也就是緩存失效時,就會調用該委托,重新整理緩存中的資料。
最後我們把dataset連同onremove委托一起插入到緩存中,在session_start中,為了“保險“,我另外添加了一個判斷來調用refreshcache方法填充緩存。
到這裡,我們應用程式就建立好了,在任何頁面中都可以通路到緩存的dataset。在webform1aspx中,我示範了如何使用它。
privatevoidpage_load(objectsender,system.eventargse)
//保證緩存非空,如果為空,則填充它
if(cache["employees"]==null)
cachestatus.text="cacherefreshedat"+datetime.now.tolongtimestring();
else
cachestatus.text="datasetfromcache";
datasetds=(dataset)cache["employees"];
datagrid1.datasource=ds.tables[0];
datagrid1.databind();
現在,如果你請求這個頁面,它将會每次成功的顯示從從cache中取得的dataset,如果你保持浏覽器打開,同時打開sqlserver的查詢分析器,選擇northwind資料庫,執行sql語句'updateemployeessetlastname='davovlieu'whereemployeeid=1',更新表中的記錄,然後重新請求該頁面,你将會看到緩存已經失效并重新整理。