Mellékelt példánkban két web lapot tartalmazó programot készítünk. Az elsőt a WebForm1.aspx szolgáltatja és egy MS SQL adatbázisban futtatott lekérdezés eredményét fogja a cache-be helyezni és szükség esetén onnan felhasználni. A második oldalon, a WebForm2.aspx-nél egy TXT állomány tartalmát helyezzük a cache-re, méghozzá úgy, hogy ha annak tartalma változna, akkor a cache-ben tárolt adatok automatikusan érvényüket veszítsék.
Menjünk sorban, és nézzük az első oldal létrehozását. A Page_Load eseménynél gondoskodunk a DataGrid-ben megjelenítendő adatok létrehozásáról. Ennek két módja lehet: vagy a cache-ből vesszük az adatokat, vagy ha ott nem állnak rendelkezésre, akkor futtatunk egy lekérdezést a Northwind példaadatbázisra. Nyilvánvaló, hogy a web oldal első megjelenítésekor a cache-ben még nem lesz adat, így ekkor csak a lekérdezés marad megoldásként.
private void Page_Load(object sender, System.EventArgs e)
{
Első lépésként tehát azt kell ellenőriznünk, hogy a cache-ben található-e adat. A cache műveletekhez a Cache osztályt kell használnunk. Ennek Item property-jén keresztül érhetjük el a cache-ben tárolt adatokat, melyeknek mi adhatunk egyedi nevet. A most tárolandó lekérdezésünk eredményhalmazának a ProductData nevet választottuk. A tárolásra kerülő adat nem más, mint egy DataView osztály. Így az alábbi sorral megpróbáljuk ezt az eltárolt adatot beolvasni egy DataView osztályba.
DataView dv = (DataView)Cache["ProductData"];
Ha a cache-ben nem található ProductData nevű objektum, akkor a visszatérési érték null.
Ebben az esetben tudhatjuk, hogy a keresett adat a cache-ben nem található meg, így kénytelenek vagyunk egy lekérdezést futtatni. Az MS SQL szerverrel való kapcsolatfelvételre az alábbi sornál szükség esetén meg kell változtatnia a server, User ID és Password paraméterek értékét.
SqlConnection connection = new SqlConnection("server=;User ID=sa;Password=;database=Northwind;Trusted_Connection=yes");
A lekérdezéshez egy SqlDataAdapter osztályt használunk és a Product tábla összes sorából a ProductID és ProductName mezőket kérdezzük le.
SqlDataAdapter da = new SqlDataAdapter("select ProductID, ProductName from Products", connection);
Létrehozunk és feltöltünk egy DataSet osztályt a lekérdezés eredményével.
DataSet ds = new DataSet();
da.Fill(ds, "Products");
Majd kreálunk egy új DataView osztályt az adatok megjelenítése érdekében, valamint majd ezt az objektumot helyezzük el a cache-ben is.
dv = new DataView(ds.Tables["Products"]);
A cache-ben történő elhelyezésre ismét a Cache osztályt használjuk.
Cache["ProductData"] = dv;
Label1.Text = "Az adatok lekérdezés útján jöttek létre.";
Button1.Enabled = false;
}
else
{
Abban az esetben, ha az első sorban lévő cache lekérdezés nem null értéket adott vissza, vagyis a ProductData nevű objektum már megtalálható a cache-ben, akkor nincs más teendőnk, mint ezt jelezni, hiszen ekkor a dv nevű DataView osztály már tartalmazza a lekérdezés eredményét.
Label1.Text = "Az adatok a cache-ből származnak.";
Button1.Enabled = true;
}
Így a megjelenítéshez már csak arra van szükségünk, hogy a DataGrid-hez kapcsoljuk a DataView osztály adatait.
DataGrid1.DataSource=dv;
DataGrid1.DataBind();
}
A programot futtatva, ha böngészőben felváltva kattintunk a WebForm1 és WebForm2 linkre, akkor látható, hogy a Label1 szövege az első kéréskor még azt jelzi, hogy „az adatok lekérdezés útján jöttek létre”, majd az ezt követő esetekben már csak „az adatok a cache-ből származnak” jelzés látható. Ezzel elértük a kívánt célt: az adat lekérdezés csak egyszer történik meg, majd ezután már a memóriából történik az adatok előkeresése.
Lehetőségünk van arra is természetesen, hogy a cache-ből eltávolítsunk egy-egy objektumot. Ehhez a Cache osztály Remove függvényét kell meghívnunk, paraméterként a törlendő objektum nevét átadni.
private void Button1_Click(object sender, System.EventArgs e)
{
Cache.Remove("ProductData");
Response.Redirect("WebForm1.aspx");
}
Ezt kipróbálva látható, hogy a törlés után megjelenő oldalon ismét az adatbázisból történt meg a lekérdezés.
Nézzük most a második oldal elkészítését. Itt az a feladat, hogy egy Data.txt nevű állomány tartalma jelenjen meg egy web lapon úgy, hogy a Data.txt a cache-en legyen tárolva a további felhasználáshoz. További cél, hogy ha a Data.txt tartalma változik, akkor a cache-en tárolt adat érvénytelenítve legyen.
Ennek az oldalnak a teszteléséhez tegye a következőket:
- Nyissa meg ezt az oldalt.
- Kattintson többször a Frissítés (Refresh) gombra. Első alkalommal az állomány beolvasásra kerül, a további alkalmakkor már a cache-ből jön az adat.
- Változtassa meg a Data.txt tartalmát, miközben a böngészőt hagyja a WebForm2.aspx oldalon.
- Ismét frissítse az oldalt a böngészőben. Mivel a Data.txt tartalma változott, most ismét beolvasásra kerül és újbóli tárolásra a cache-re.
A megvalósítás hasonló az előző oldaléhoz. Először itt is ellenőrizzük, hogy a szükséges adat már megtalálható-e a cache-en. Ennek most StringData nevet adtunk. Az objektum pedig egy egyszerű string objektum, mely tartalmazza a Data.txt állomány teljes szövegét sztringként.
Lekérdezzük tehát az objektumot a cache-ből, majd ismét ellenőrizzük, hogy létezett-e már ez az objektum, vagyis a visszaadott érték null-e vagy sem.
private void Page_Load(object sender, System.EventArgs e)
{
string s = (string)Cache["StringData"];
if (s == null)
{
Ha még nem volt a cache-en tárolva, akkor kénytelenek leszünk beolvasni a tartalmat a háttértárról. Ehhez a StreamReader osztályt használjuk.
StreamReader sr = new StreamReader(Server.MapPath("data.txt"));
Ennek ReadToEnd függvénye egy lépésben beolvassa és sztringként visszaadja a txt tartalmát.
Zárjuk az állományt a Close-al.
Majd elhelyezzük a kapott sztringet a Cache-ben. Itt most a Cache osztály Insert függvényét használjuk. Ennek első paraméterében megadjuk az objektumunk nevét, másodikban pedig a tárolandó objektumot. A harmadik paraméterben rendelkezünk arról, hogy milyen függőségi viszony áll fenn a tárolt adattal kapcsolatban. Itt egy CacheDependency osztály példányát kell átadnunk, melyet most úgy hozunk létre, hogy paraméterként megadjuk annak az állománynak az elérési útvonalát és nevét, melytől függ a cache-ben tárolt adat. Így ettől kezdve nincs gondunk a tárolt adatra, hiszen ha az itt megadott állomány tartalma megváltozik, akkor a cache-ből automatikusan törölve lesz a StringData objektumunk, így a következő web kérésnél ismét be kell olvasnunk annak tartalmát.
Cache.Insert("StringData", s, new CacheDependency(Server.MapPath("data.txt")));
Label1.Text = "Az adatok a Data.txt-ből lettek beolvasva.";
}
Ha az adat már megtalálható volt a cache-ben, akkor nincs különösebb dolgunk, mint jelezni ezt.
else
{
Label1.Text = "Az adatok a cache-ből származnak.";
}
Végezetül megjelenítjük az adatot egy Label kontrol segítségével.
Amint a fentiekből látható is a Cache-re bármilyen típusú objektumot helyezhetünk, nem csak egy lekérdezés eredményét, vagy egy sztringet. Ezt kihasználva nagymértékben gyorsíthatjuk a feldolgozást és csökkenthetjük rendszerünk terhelését.