dùng Cache trong ASP.NET

Bài này đề cập tới DataCaching của ASP.NET. Các vấn đề outputCaching (cache cả trang aspx) và fragmentCaching (cache một ascx, một phần của trang Aspx) là khá dễ, chỉ cần setup vài thẻ trong mã aspx là xong nên không được đề cập trong bài.

Xem thêm tại http://aspnet.4guysfromrolla.com/articles/022802-1.aspx

Cache về bản chất giống như một HashTable, lưu key là một String, value là đối tượng .NET. Tuy nhiên Cache thì có tính năng đặc biệt là tự động gỡ bỏ các entry theo thời gian hoặc khi hết bộ nhớ để lưu.

Truy xuất Cache:

dùng đối tượng tĩnh HttpContext.Current.Cache
nếu trong Page aspx, dùng Server.Cache
nếu trong ashx, dùng context.Cache

tất cả đều truy xuất đến cùng một chỗ lưu cache của ASP.NET.

Có hai kiểu chính sách hết hiệu lực bạn có thể sử dụng khi lưu giữ dữ liệu trong cache.

  • Absolute expiration: hết hiệu lực vào một THỜI ĐIỂM xác định trong tương lai (VD: 10 phút nữa là huỷ đổi tượng).

Cache.Insert("cacheKey", ObjectToCache, null, DateTime.Now.AddMinutes(10), TimeSpan.Zero);

  • Sliding expiration: gỡ bỏ các đối tượng sau một khoảng thời gian không dùng đến. Mỗi khi đối tượng được truy xuất, thời gian sống của nó sẽ được reset. (VD: loại bỏ các đối tượng mà đã lâu (10 phút) không dùng tới)

Cache.Insert("cacheKey", ObjectToCache, null,DateTime.MaxValue, TimeSpan.FromMinutes(10));

Mẫu code chung để sử dụng Cache là:

T GetValue(){
string CACHE_KEY = "cacheKey";
object oValue = cache[CACHE_KEY];
if (oValue == null) {
oValue = GetValueFromSomeWhere();
// Lưu giữ đối tượng theo kiểu nào tuỳ bạn chọn
cache.Insert(CACHE_KEY, oValue, null, DateTime.MaxValue, TimeSpan.FromSeconds(60));
}
return oValue as T;
}

Hàm GetValueFromSomeWhere() là chỗ bạn lấy dữ liệu thực ở đâu đó (VD lấy từ Database, đọc từ file …)

.

Một  số bonus:
Hàm Cache.Insert() có đối số cuối cùng là CallBack. Tính năng này khá tiện, cho phép developer kiểm soát xem nên làm gì mỗi khi Cache entry bị gỡ bỏ (có thể kiểm tra, tạo lại mới luôn, hoặc thực hiện một số tác vụ …) .  Tips: Dùng cái này có thể tránh được việc pooling để kiểm tra xem Cache entry hết hạn chưa.

Callback này không được khởi chạy nếu cache entry bị gỡ bỏ có chủ ý (bằng cách gọi Remove(), hay gọi Insert() mới đè lên)

Hàm Cache.Insert() nếu cung cấp key trùng với key đã có rồi sẽ gỡ bỏ entry cũ, ấn entry mới vào với key tương ứng ấy

Cache control problem with IE6 when do Ajax site call XML API

When create ajax site, we let client browser use js to make some call to our API services (REST). API function return output as XML (our format). Then the js at browser parse the return XML to display some fancy on screen.

Firefox, Mozzila base work fine, but IE6 is so stupid and lazy. IE6 cache the return XML data, and later call to API (with the same URL), IE6 take data from it internal cache, avoid calling from API.

To avoid it, our API server must send some header(s), tell the browser (client) NOT TO CACHE the XML data (fetching from API). You must do it from SERVER, remember.

Here is correct sequence (write in PHP), work for IE6

header(“Expires: Mon, 26 Jul 1997 05:00:00 GMT”);
header(“Last-Modified: ” . gmdate(“D, d M Y H:i:s”) . ” GMT”);
header(“Cache-Control: no-store, no-cache, must-revalidate”);
header(“Cache-Control: post-check=0, pre-check=0”, false);
session_start();
header(“Cache-Control: private”);

But, beside the problem with IE (while using js, make ajax call to XML file), using caching with API oriented and ajax call is very sweet.

Some resource I found here about caching:

http://www.htaccesselite.com/using-php-header-function-vt156.html
http://www.phpbuilder.com/board/showthread.php?t=10294526
http://www.websiteoptimization.com/speed/tweak/cache/
http://www.chriskirkland.net/news/59_PHP-Cache-Control-script.html
http://www.badpenguin.org/docs/php-cache.html
http://www.mnot.net/cache_docs/
http://www.htaccesselite.com/using-php-header-function-vt156.html