亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Scott Mitchell 的ASP.NET 2.0數據教程之60:在

系統 2156 0


本文英文原版及代碼下載:
http://www.asp.net/learn/dataaccess/tutorial60cs.aspx?tabid=63

Scott Mitchell 的ASP.NET 2.0數據教程之60:在程序啟動階段緩存數據

導言:
前面2章考察了在表現層和緩存層緩存數據。在第58章,我們探討了在表現層設置ObjectDataSource的相關cache屬性來緩存數據。在第59章,我們探討了創建一個單獨的分開的緩存層。這2章都是采用“應激裝載”(reactive loading)的模式來緩存數據。該模式下,每次請求數據時,系統先檢查其是否在內存,如果沒有,則從數據源——比如數據庫,來獲取數據,然后將其存儲在內存里。該模式的優勢在于執行起來很容易;而缺點之一在于應“請求”(requests)而執行。試想一下,在前面章節,我們通過緩存層來展示產品信息,當第一次登錄該頁面,或緩存數據因為緩存時間結束等原因從內存清除以后,再次訪問該頁面時,因為數據沒有儲存在內存里,請求只能從數據庫獲取數據。這樣一來花的時間就比直接從內存獲取數據要長一些。

“預裝載”(Proactive loading)可以使用2種模式來預裝載數據。第一種模式,Proactive loading使用一些方法( process)來判斷源數據(underlying data)是否發生改變,并及時對緩存數據進行更新——比如,周期性的檢查源數據;或者當源數據發生改變時,立即通知更新。不過該模式的弊端在于執行起來比較困難,你必須創建、管理、執行一個具體的方法來檢查源數據的更改情況,以更新緩存數據。

另一個模式,同時也是本文要探討的內容,就是在程序啟動時便裝載數據入內存。該模式對緩存靜態數據(static data)尤其有用,比如查找數據庫表里的記錄。
注意:關于“應激裝載”(reactive loading)和“預裝載”(proactive loading)的區別,請參考文章《 Caching Architecture Guide for .NET Framework Applications》的《Managing the Contents of a Cache》章節:( http://msdn2.microsoft.com/en-us/library/ms978503.aspx )


第一步:在程序啟動階段決定緩存哪些數據

我們在前面2章探討的reactive loading模式的示例適合處理這些數據:周期性地改變且生成(generate)數據不需要太長的時間。但是,如果緩存的數據從未改變,那么reactive loading模式使用的周期(expiry)就顯的有點多余。另外,如果需要緩存的數據要花很長的時間才能生產,當用戶請求發現內存為空時,用戶將等很長的時間來檢索并返回數據。對此,可以考慮將靜態數據和需要很長時間才能生成的數據在程序啟動階段就緩存。

雖然,數據庫有很多動態的,經常改變的值;不過靜態值也不少。舉例,數據庫表Patients有一個PrimaryLanguage列,其值可以為English, Spanish, French, Russian, Japanese等。不過我們不會直接在表Patients里存儲“English”或 “French”等字符串,而是在供查找的表Languages里存儲。如圖1:John Doe的primary language是English,而Ed Johnson的是Russian.

Scott Mitchell 的ASP.NET 2.0數據教程之60:在程序啟動階段緩存數據
圖1:表Languages為表Patients所使用的查找表

在編輯或創建新patient的用戶界面里,將包含一個下拉列表框,列出表Languages里的所有語言項。不緩存的話,每次登錄該界面,系統都會查詢表Languages,這樣顯地和浪費也沒有必要。因為表Languages不會頻繁的改變。

我們可以用前面探討的reactive loading模式來對數據Languages進行緩存。不過,reactive loading模式會使用基于時間的緩存周期(time-based expiry),這對靜態數據來說沒有必要。最好的辦法是在程序啟動階段進行預裝載。


在本文,我們將探討如何緩存“查找表”(lookup table,例如Languages表對Patients表來說就是查找表)數據和其它的靜態信息。


第二步:考察緩存數據的不同途徑

在一個ASP.NET應用程序里,我們可以使用多種方法來緩存信息。在前面的教程我們看到的是data cache,其實通過使用static members(靜態成員)或application state(應用程序狀態)我們也可以將對象(objects)緩存。

當處理一個類時,我們在訪問其成員(members)前,應先實例化。比如,為了調用BLL層里的一個方法,我們首先要創建該類的實例:

ProductsBLL productsAPI = new ProductsBLL();
productsAPI.SomeMethod();
productsAPI.SomeProperty = "Hello, World!";

在調用SomeMethod或處理SomeProperty之前,我們必須首先用關鍵字new來創建一個類的實例。SomeMethod 和 SomeProperty要與一個具體的實例對應起來,這些成員的生命周期(lifetime)取決與對應對象的生命周期。另一方面,Static members,比如變量、屬性、方法等,對該類的所有實例來說都是共享的,因此其生命周期與該類的生命周期一樣長。Static members要用關鍵字static來標識。

除了static members外,還可以使用application state。每一個ASP.NET應用程序都包含一個name/value集,它對應用程序的所有頁面和用戶都是共享的。可以通過HttpContext class類的Application property屬性來訪問它。在頁面的后臺代碼我們可以這樣訪問它:

Application["key"] = value;
object value = Application["key"];

data cache提供了豐富的緩存數據的API(應用程序接口),基于時間和從屬體的緩存周期(time- and dependency-based expiries)的機制,以及cache item priorities等。在本文,我們將看到3種緩存靜態數據的技術。

第三步:緩存Suppliers Table表的數據

我們用到的Northwind數據庫并沒有“查找表”(lookup tables),DAL層用到的4個表的值也并非靜態的。沒必要花時間來向DAL層添加一個新數據庫表,再在BLL層添加新的類和新的方法,我們在本教程假定表Suppliers的數據是靜態的,因此我們在程序啟動是緩存其數據。

首先,我們在CL文件夾里創建一個名為StaticCache.cs的新類。

Scott Mitchell 的ASP.NET 2.0數據教程之60:在程序啟動階段緩存數據

圖2:在CL文件夾里創建StaticCache.cs類

我們需要添加一個在程序啟動時裝載數據的方法;同樣,還有一個從內存返回數據的方法。

[System.ComponentModel.DataObject]
public class StaticCache
{
private static Northwind.SuppliersDataTable suppliers = null;

public static void LoadStaticCache()
{
// Get suppliers - cache using a static member variable
SuppliersBLL suppliersBLL = new SuppliersBLL();
suppliers = suppliersBLL.GetSuppliers();
}
[DataObjectMethodAttribute(DataObjectMethodType.Select, true)]
public static Northwind.SuppliersDataTable GetSuppliers()
{
return suppliers;
}
}

在上述代碼里,我們在LoadStaticCache()方法里,用一個static member變量suppliers來保存SuppliersBLL類的GetSuppliers()方法返回的結果。該LoadStaticCache()方法應該在程序啟動階段就被調用。一旦數據在啟動時就被加載到內存,任何要用到supplier信息的頁面都可以調用StaticCache class類的GetSuppliers()方法。因此,訪問數據庫獲取suppliers信息的情況只會發生一次,就是在啟動階段。

除了static member變量外,我們還可以使用application state 或data cache。下面的代碼將類進行修改,它使用application state:

[System.ComponentModel.DataObject]
public class StaticCache
{
public static void LoadStaticCache()
{
// Get suppliers - cache using application state
SuppliersBLL suppliersBLL = new SuppliersBLL();
HttpContext.Current.Application["key"] = suppliersBLL.GetSuppliers();
}

[DataObjectMethodAttribute(DataObjectMethodType.Select, true)]
public static Northwind.SuppliersDataTable GetSuppliers()
{
return HttpContext.Current.Application["key"] as Northwind.SuppliersDataTable;
}
}

在LoadStaticCache()方法里,supplier信息是存儲在application變量key里。在GetSuppliers()方法里,它作為Northwind.SuppliersDataTable類型返回。由于我們可以在ASP.NET頁面的后臺代碼里使用Application["key"]來訪問application state,所以,在這里我們必須使用HttpContext.Current.Application["key"]來獲取當前的HttpContext。


同樣,我們可以使用data cache,如下所示:

[System.ComponentModel.DataObject]
public class StaticCache
{
public static void LoadStaticCache()
{
// Get suppliers - cache using the data cache
SuppliersBLL suppliersBLL = new SuppliersBLL();
HttpRuntime.Cache.Insert(
/* key */ "key",
/* value */ suppliers,
/* dependencies */ null,
/* absoluteExpiration */ Cache.NoAbsoluteExpiration,
/* slidingExpiration */ Cache.NoSlidingExpiration,
/* priority */ CacheItemPriority.NotRemovable,
/* onRemoveCallback */ null);
}

[DataObjectMethodAttribute(DataObjectMethodType.Select, true)]
public static Northwind.SuppliersDataTable GetSuppliers()
{
return HttpRuntime.Cache["key"] as Northwind.SuppliersDataTable;
}
}

向data cache添加一個條目,且沒指定時間周期(no time-based expiry)為此,我們System.Web.Caching.Cache.NoAbsoluteExpiration 和 System.Web.Caching.Cache.NoSlidingExpiration值作為輸入參數之一。在上面的data cache的Insert()方法里,我們指定了緩存條目的優先級(priority).優先級用以指明當內存容量不足時,哪些條目應從內存移除。在此,我們將優先級設為不可移除(也就是對應的null),這就確保了當內存不足時不會將其移除。
注意:本文下載代碼里的StaticCache class類使用的是 static member變量技術,關于application state 和 data cache技術的代碼可以在類文件(class file)里的注釋部分找到。

第四步:在程序啟動是執行代碼

為了在程序啟動時執行代碼,我們需要創建一個名為Global.asax的文件。該文件包含了application、session和request級事件的事件處理器。在該文件里我們將添加在程序啟動時要執行的代碼。

要在網站根目錄里添加Global.asax文件,在Visual Studio解決資源管理器里,右擊網站項目,選Add New Item,從Add New Item對話框里選擇Global應用程序項目類型,然后點Add按鈕。
注意:如果你的根目錄里已經存在Global.asax文件,Global應用程序項目類型就不會出現在Add New Item對話框里。

Scott Mitchell 的ASP.NET 2.0數據教程之60:在程序啟動階段緩存數據
圖3:在根目錄添加Global.asax文件。

默認的Global.asax文件里包括了5個方法,每個方法都有一個服務器端(server-side)<script>標記:

Application_Start –當程序啟動時執行

Application_End – 當程序完結時執行

Application_Error – 每當程序發生未經處理(unhandled)的異常時發生。

Session_Start – 當創建一個session時執行

Session_End – 當session完結時或被移除時發生

Application_Start事件處理器在程序的生命周期(life cycle)里只發生一次。程序起始于一個ASP.NET資源(resource)首次被請求,持續運行直到程序重新啟動為止。關于程序生命周期的更多細節請參閱文章《ASP.NET Application Life Cycle Overview》 http://msdn2.microsoft.com/en-us/library/ms178473.aspx

本文,我們只需要為Application_Start方法添加代碼,放心大膽的將其它方法刪除。在Application_Start里,僅僅調用StaticCacheclass類的LoadStaticCache()方法。這將裝載并緩存supplier信息:

<%@ Application Language="C#" %>
<script runat="server">
void Application_Start(object sender, EventArgs e)
{
StaticCache.LoadStaticCache();
}
</script>


要做的就是這些!在程序開始時,LoadStaticCache()方法會從BLL獲取supplier信息,再存儲進一個static member變量(或是你在StaticCache class類里面用的其它一些cache store)。為驗證起見,在Application_Start 方法里設置斷點(breakpoint)并執行程序。另外,在并發請求(Subsequent requests)時,不會執行Application_Start方法。

Scott Mitchell 的ASP.NET 2.0數據教程之60:在程序啟動階段緩存數據

圖4:用Breakpoint來驗證Application_Start事件處理器的執行

注意:如果你在首次調試時沒有遇到Application_Start breakpoint,那是因為你的程序已經啟動了。可以修改Global.asax 或 Web.config文件來強迫程序重新啟動。你僅僅在這些文件的末尾添加(或刪除)一個空白行來快速的重啟程序。

第五步:展示緩存數據

現在,StaticCache class類在程序啟動時將supplier相關的數據進行了緩存。要在表現層使用這些數據,我們可以在ASP.NET頁面的后臺代碼通過ObjectDataSource控件或編程調用StaticCache class類的GetSuppliers()方法。讓我們看看如何使用ObjectDataSource 和 GridView控件來展示緩存的supplier信息。

首先,打開文件夾里的AtApplicationStartup.aspx頁面,在“設計”模式里從工具箱里拖一個GridView控件到頁面,設置其ID為Suppliers。然后,從其智能標簽里選擇創建一個新的ObjectDataSource,名為SuppliersCachedDataSource,設置它使用StaticCache class類的GetSuppliers()方法。

Scott Mitchell 的ASP.NET 2.0數據教程之60:在程序啟動階段緩存數據

圖5:設置ObjectDataSource控件使用StaticCache Class類

Scott Mitchell 的ASP.NET 2.0數據教程之60:在程序啟動階段緩存數據
圖6:使用GetSuppliers()方法來獲取緩存的Supplier數據


完成設置后,Visual Studio會自動的為SuppliersDataTable里的每一個列添加一個BoundFields。因此,你的GridView 和 ObjectDataSource控件的聲明標記看起來應該像下面這樣:

<asp:GridView ID="Suppliers" runat="server" AutoGenerateColumns="False"
DataKeyNames="SupplierID" DataSourceID="SuppliersCachedDataSource"
EnableViewState="False">
<Columns>
<asp:BoundField DataField="SupplierID" HeaderText="SupplierID"
InsertVisible="False" ReadOnly="True"
SortExpression="SupplierID" />
<asp:BoundField DataField="CompanyName" HeaderText="CompanyName"
SortExpression="CompanyName" />
<asp:BoundField DataField="Address" HeaderText="Address"
SortExpression="Address" />
<asp:BoundField DataField="City" HeaderText="City"
SortExpression="City" />
<asp:BoundField DataField="Country" HeaderText="Country"
SortExpression="Country" />
<asp:BoundField DataField="Phone" HeaderText="Phone"
SortExpression="Phone" />
</Columns>
</asp:GridView>

<asp:ObjectDataSource ID="SuppliersCachedDataSource" runat="server"
OldValuesParameterFormatString="original_{0}"
SelectMethod="GetSuppliers" TypeName="StaticCache" />

圖7顯示的是在瀏覽器登錄該頁面的畫面。同樣都是用BLL層的SuppliersBLL class類來獲取數據,不同的是我們用StaticCache class類在程序開始時將數據緩存并將其返回。你可以在StaticCache class類的GetSuppliers()方法里設置斷點來進行驗證。

Scott Mitchell 的ASP.NET 2.0數據教程之60:在程序啟動階段緩存數據
圖7:將緩存的Supplier數據顯示在GridView控件


結語:

幾乎每一種數據模式(data model)都包含有靜態數據,且通常情況下都會用到對應的"查找表"(lookup tables)。正因為這些信息是靜態的,所以沒有必要每次展示數據時都訪問數據庫。此外,因其“靜態”的本質,當緩存數據時沒有必要設置周期(expiry).在本文,我們看到了如何用data cache, application state和static member變量來緩存數據。這些數據在程序啟動是就進行緩存,且貫穿程序的整個生命周期(lifetime)中,都會保留在內存里。

在本文及前面2章,我們探討了在程序的生命周期內緩存數據,以及使用基于時間的緩存周期(time-based expiries)。當緩存數據庫數據時,若源數據(underlying database data)改變時我們應將對應的緩存條目移除。在這個問題的處理上,雖然使用基于時間的緩存周期的方法還算不上完美,但與通過編程來“刷新”數據相比,還算上佳方案。最佳方案或許是使用SQL cache dependencies,對此,我們將在接下來的文章繼續探討。

祝編程快樂!

作者簡介

Scott Mitchell,著有六本ASP/ASP.NET方面的書,是4GuysFromRolla.com的創始人,自1998年以來一直應用 微軟Web技術。Scott是個獨立的技術咨詢顧問,培訓師,作家,最近完成了將由Sams出版社出版的新作,24小時內精通ASP.NET 2.0。他的聯系電郵為 mitchell@4guysfromrolla.com ,也可以通過他的博客 http://ScottOnWriting.NET 與他聯系。

Scott Mitchell 的ASP.NET 2.0數據教程之60:在程序啟動階段緩存數據


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 九九热视频免费在线观看 | 欧美久久久久久久一区二区三区 | 亚洲精品美女久久久aaa | 色天天色综合 | 曰韩一级片 | 日韩欧美国产亚洲 | 12345国产精品高清在线 | 中文字幕精品一区二区三区视频 | 国产精品女在线观看 | 婷婷国产成人久久精品激情 | 91色综合久久 | 精品国产免费久久久久久婷婷 | 国产三级精品三级男人的天堂 | 色综合网亚洲精品久久 | 亚洲精品911| 国产精品视频一区牛牛视频 | 一区二区亚洲视频 | 5060午夜一级毛片免费观看 | 御姐色网 | 久久久久久久91精品免费观看 | 国产成人免费在线视频 | 久久精品人人做人人看最新章 | 日本囗交做爰视频欧美 | 欧美日韩高清一区 | 国产凹凸在线一区二区色老头 | 天码毛片一区二区三区入口 | 五月花精品视频在线观看 | 成人在线黄色 | 日日操网站 | 女性一级全黄生活片免费看 | 国产尤物视频在线 | 青青青青久在线观看视频 | 天天干天天射天天插 | 欧美成人精品高清在线观看 | 最新日本免费一区二区三区中文 | 国产欧美另类久久精品91 | 久久综合图区亚洲综合图区 | 米奇精品一区二区三区在线观看 | 99热播在线观看 | 国产高清一区二区三区四区 | 久热热热|