ASPNET中的新狀態容器
前面我們提到ASPNET為保存用戶請求間的數據添加了幾種新的途徑這些途徑給了你如何保持狀態信息更好的控制這些技術的范圍可以窄到只有一個請求那麼小(Context對象)也可以寬到整個Web服務器和服務器上的所有應用程序(Machineconfig文件)在多數情況下你有多種保存特定數據片的選擇使用每個方法描述的問題和答案來決定某個對象是否適合你的需要
Cache
Cache對象用於單個用戶一組用戶或所有的用戶這種數據為多個請求保持它可以保持很長時間但是不能超過應用程序重新啟動的時間並且數據的終止基於時間或者其它的依賴關系它可以高效率地保持大量或少量地數據
Cache 是ASPNET中最酷的對象之一它提供了難以置信的靈活性通用性和性能因此在ASPNET應用程序中它通常是比Application或Sessions更好的保持數據的對象本文沒有詳細介紹Cache對象的使用方法但是仍然可以說它是一個萬能對象與其它的集合對象相似它是一個簡單的名稱-值集合但是通過使用指定特定用戶的鍵值可以緩存特定用戶的值同樣你可以緩存不同的相關數據的多個數據集例如幾個有鍵(如fordcars chevycarsgmcars)的汽車集合Cache中的數據可以給定一個絕對的可變的或基於文件的終止時間它們也實現了一個回調功能在被緩存的值從緩存中提取時被調用這個功能很有用因為接著你能檢查它是否為最新的數據變量如果不是(或數據源不可用)就重新緩存被終止的值
添加和訪問緩存中值的語法與先前談到的相似但是Cache給訪問集合內容的標准索引器方法作了補充它支持多種方法允許對被緩存數據的更多的控制最頻繁使用的方法是Insert它支持幾種重載允許你指定依賴超時值優先級和回調下面是一些簡單的例子
// 給緩存添加項
Cache[myKey] = myValue;
// 從緩存中讀取項
ResponseWrite(Cache[myKey]);
// 把CacheDuration增加秒並把項添加到緩存中
CacheInsert(myKeymyValue null SystemDateTimeNowAddSeconds()
SystemWebCachingCacheNoSlidingExpiration);
Cache對象的最強大的特性之一是當緩存中的某個項終止時執行回調的能力它使用了委托或函數指針這在本文中沒有討論幸運的是一旦你有了某些這些技術怎樣工作的示例就能通過簡單的剪切和粘貼在應用程序中使用它們不需要知道委托是怎樣工作的復雜過程有很多使用這種功能的原因最通常的是在數據終止時用當前數據重新填充緩存或者如果重新填充緩存的數據源不可用時恢復舊的緩存數據
在我的例子中簡單地緩存了當前時間當緩存超期的時候我將給緩存中的字符串末尾添加一個星號(*)在超過時間後你能通過計算星號的數量來確定緩存超期了多少次圖演示了回調的重要概念並且提供了給使用緩存建立更多功能回調程序的好模板
private void Page_Load(object sender SystemEventArgs e)
{
string cacheKey = myKey;
string data = ;
// 檢查數據是否已經被緩存了
if(Cache[cacheKey]==null)
{
// 因為數據在緩存中所有讀取數據
data = SystemDateTimeNowToString();
//建立回調委托的一個實例
CacheItemRemovedCallback callBack =new CacheItemRemovedCallback(onRemove);
LabelText = Generated: + data;
CacheInsert(cacheKeydatanull
SystemDateTimeNowAddSeconds()
SystemWebCachingCacheNoSlidingExpiration
SystemWebCachingCacheItemPriorityDefault
callBack);
}
else
{
LabelText = Cached: + Cache[cacheKey]ToString();
}
}
private void onRemove(string key object valCacheItemRemovedReason reason)
{
//建立回調委托的一個實例
CacheItemRemovedCallback callBack =new CacheItemRemovedCallback(onRemove);
CacheInsert(keyvalToString() +
*nullSystemDateTimeNowAddSeconds()CacheNoSlidingExpiration
SystemWebCachingCacheItemPriorityDefault callBack);
}
代碼段緩存回調示例
注意代碼段中一個重要的特性是在Page_Load中使用模式(pattern)來確定是否使用緩存中的數據當你處理緩存中的項時也可能使用這種模式使用if語句來檢查緩存的當前內容是否為空(因為要多次引用為緩存鍵使用了一個變量)如果是空的從數據源生成數據並放入緩存中如果不是空的從緩存中返回數據如果數據訪問邏輯很復雜你需要把整個if語句放入一個獨立的函數該函數的任務是檢索數據
Cache對象的功能比先前我們討論的大多數對象多得多這也是ASPNET更強大的功能之一並且我明確地推薦閱讀關於它的更多內容
Context
Context對象保持單個用戶單個請求的數據並且數據只在該請求期間保持Context容器可以保持大量的數據但是典型的情況下是保存小的數據片因為它經常通過globalasax中的某個處理方法為每個請求實現
Context容器(從Page對象訪問或使用SystemWebHttpContextCurrent)被提供用於保持需要在不同的HttpModules和HttpHandlers之間傳遞的值它也可以用於保持某個完整請求的相應信息例如IbuySpy入口在globalasax中的Application_BeginRequest事件過程中給容器填滿了許多配置信息注意這只在當前請求中可用如果你希望在下一個請求中也能使用請考慮使用ViewState
從Context集合中設置和獲取數據使用的語法與前面討論的其它集合對象(如ApplicationSessions和 Cache)的相似下面是兩個簡單的例子
// 給Context添加項
ContextItems[myKey] = myValue;
// 從Context中讀取項
ResponseWrite(Context[myKey]);
ViewState
ViewState為單個用戶保持狀態信息保持期為ASPX頁面工作時間ViewState容器可以保持大量的數據但是必須小心管理ViewState的大小因為它增加了每個請求和回應的下載(download)大小
ViewState是ASPNET中的一個新容器也許你已經使用它了但是你可能還是不了解它這是因為所有的內建Web控件都使用ViewState在頁面回發(postback)間保持自己的值但是你必須小心因為它影響應用程序的性能影響的大小依賴於回發之間使用ViewState的多少對大多數Web窗體來說數量非常小
確定某個頁面上每個控件使用的ViewState的數量最簡單的方法是打開頁面追蹤並檢查每個控件負載了多少個ViewState如果某個特定控件不需要在回發之間保持數據請通過把EnableViewState設置為false關閉該對象的ViewState你也可以通過在浏覽器中查看的HTML源並檢查隱藏窗體字段__VIEWSTATE來確定某個給定的ASPNET頁面ViewState的總共大小注意這些內容都是使用Base編碼的用於放置偶然的查看和維護ViewState也可以通過給@Page指令添加EnableViewState=false在整個頁面中禁止
典型的Web窗體不需要直接維護ViewState但是如果你建立自定義Web控件就需要了解它是怎樣工作的並為你的控件實現它這樣該控件的工作方式才能與隨ASPNET發布的Web控件同樣地工作向ViewState讀取或寫入值都可以通過上面討論地其它集合對象的語法完成
// 給ViewState添加項
ViewState[myKey] = myValue;
//從Context讀取項
ResponseWrite(ViewState[myKey]);
當建立自定義Web控件時你也許希望它們有ViewState的好處這在控件的屬性層可以簡單實現代碼段演示了怎樣保存一個簡單的自定義控件的PersonName屬性到ViewState中並在該控件的Render方法中使用它
namespace MSDNStateManagement
{
public class HelloPerson : SystemWebUIControl
{
public string PersonName
{
get
{
string s = (string)ViewState[PersonName];
return ((s == null) ? : s);
}
set
{
ViewState[PersonName] = value;
}
}
protected override void Render(SystemWebUIHtmlTextWriter writer)
{
writerWrite(Hello + PersonName);
}
}
}
代碼段在ViewState中保存數據
Webconfig和Machineconfig文件
這些文件中的數據對於某個應用程序的所有用戶來說都可以使用Webconfig文件中存儲的數據可用於應用程序的整個生命周期這些數據一般很小該對象一般用於保持文件位置和數據庫連接的字符串大的數據片最好保存在其它位置
作為其它多樣集合對象的補充ASPNET引入了一組XML配置文件用於管理應用程序甚至於整個服務器的很多設置每個ASPNET應用程序使用Webconfig文件來設置它的許多屬性每個服務器在系統文件夾下有一個作為應用程序基礎的Machineconfig文件這些設置都作為默認值使用除非重載作為保存配置數據的補充這些文件可以保存應用程序(或多個應用程序)需要的數據
無論什麼時候應用程序啟動都會讀取配置信息接著這些信息被緩沖由於被緩沖了應用程序可以快速讀取它們因此不需要考慮應用程序的瓶頸因為它經常執行某個文本文件的一些整型信息此外某個應用程序的Webconfig的改變將導致應用程序重新啟動這確保了對配置文件信息的修改立即反映到應用程序中
數據庫連接信息默認圖像路徑和XML數據文件路徑是通常保存在Webconfig文件中的數據片在Webconfig文件中保存數據的語法如下在理想的情況下你也許希望使用集成的SQL身分驗證
<configuration>
<!應用程序特殊設置 >
<appSettings>
<add key=connectionString value=server=myDBServer;
uid=myUID;pwd=myPassword;database=myDB />
</appSettings>
<systemweb>
<!所有的wsb設置 >
</systemweb>
</configuration>
為了訪問ASPNET頁面中的值可以使用ConfigurationSettings集合它在SystemConfiguration名字空間中下面的簡單例子演示了怎樣提取前面的連接字符串到一個本地變量中
using SystemConfiguration;
ooo
String strConnString =
ConfigurationSettingsAppSettings[connectionString];
給SystemConfiguration名字空間添加一個引用減少了引用這些值的代碼數量因為對Webconfig或 Machineconfig的修改將導致應用程序立即重新啟動典型情況下這些值只由服務器系統管理員手動修改因此你可以認為這些文件是保存只讀數據而不是應用程序中修改的數據的好位置
結論
有效的狀態管理意味著識別的用戶經驗數據錯誤與快速的頁面或事務處理之間的巨大差別盡管狀態管理在ASP 中不太適用但是ASPNET把它帶到了本文討論的狀態對象的控制之下小心地使用它們將使你給用戶展示最佳的Web經驗
From:http://tw.wingwit.com/Article/program/net/201311/15003.html