SİTE
İÇİ ARAMA |
|
|
Blogroll |
|
|
|
|
|
|
Caching Mekanizmasını Anlamak - 2 |
|
| Gönderiliyor lütfen bekleyin... |
|
|
Hatırlayacağınız gibi bir önceki
makalemizde, web uygulamalarında caching mekanizmasını incelemeye
başlamış ve ara belleğe alma tekniklerinden Output Cache yapısını
incelemiştik. Output Cache tekniğinde bir sayfanın tamamının HTML
içeriği ara belleğe alınmaktaydı. Oysa çoğu zaman sayfamızda yer alan
belirli veri kümelerinin ara bellekte tutulmasını isteyebiliriz.
Örneğin, bir alışveriş sitesinin pek çok kısmı dinamik olarak
değişebilirken satışı yapılan ürünlerin yer aldığı kategori listeleri
çok sık değişmez. Hatta uzun süreler boyunca aynı kalabilirler. İşte
böyle bir durumda sayfanın tamamını ara belleğe almak yerine sadece
kategori listesini sunan veri kümesini ara belleğe almak daha
mantıklıdır. Data Caching olarak adlandırılan bu teknikte çoğunlukla
veri kümeleri ara belleğe alınır. Data Caching tekniğinde verileri ara
belleğe almak için System.Web.Caching isim alanında yer alan
Cache sınıfı ve üyeleri kullanılmaktadır.
 |
Cache sınıfı sealed tipinde
olup kendisinden türetme yapılmasına izin vermez. Bununla
birlikte, her bir Application Domain için yanlız bir
Cache nesne
örneği oluşturulur ve kullanılır. |
Cache sınıfına bir veri kümesini
eklemek bu veriyi ara belleğe almak demektir. Bunun için aşağıdaki 4
aşırı yüklenmiş prototipe sahip olan ve bize pek çok imkan sağlayan
Insert metodunu kullanabiliriz.
| public
void Insert(string
key,object
value); |
| public
void Insert(string
key,
object
value,CacheDependency
dependencies); |
| public
void Insert(string
key,object
value,CacheDependency
dependencies,DateTime
absoluteExpiration,TimeSpan
slidingExpiration); |
| public
void Insert(string
key,
object
value, CacheDependency
dependencies,
DateTime
absoluteExpiration,TimeSpan
slidingExpiration, CacheItemPriority
priority,
CacheItemRemovedCallback
onRemoveCallback); |
Insert metodu ara belleğe alınan veri
kümesinin durumuna ilişkin olarak çeşitli imkanlar sunar. Örneğin veri
kümesinin ara bellekte ne kadar süre ile tutulacağı veya ne kadar süre
bu veriye erişilmez ise ara bellekten silineceğinin belirlenmesi
vb...Şimdi bu imkanları test etmeden önce basit olarak bir veri kümesini
Cache nesnesine nasıl ekleyeceğimizi inceleyeceğiz.
private SqlConnection con;
private SqlCommand cmd;
private SqlDataAdapter da;
private DataTable dt;
/*Categories tablosundan CategoryName alanının değerlerini
alıyoruz ve bir DataTable nesnesine aktarıyoruz.*/
private void KategorileriAl()
{
con=new SqlConnection("data source=BURKI;initial
catalog=Northwind;integrated security=SSPI");
cmd=new SqlCommand("SELECT DISTINCT CategoryName FROM
Categories",con);
da=new SqlDataAdapter(cmd);
dt=new DataTable();
da.Fill(dt);
}
private void Page_Load(object sender, System.EventArgs e)
{
//Güncel saat bilgisini label kontrolüne yazdırıyoruz.
Label1.Text=DateTime.Now.ToLongTimeString();
/*Eğer ara bellekte kategori isimli Cache nesnesinin içeriği
null ise bu durumda verileri çekiyoruz ve DataTable içeriğini
ara belleğe Cache sınıfının Insert metodu ile alıyoruz.*/
if(Cache["kategori"]==null)
{
KategorileriAl();
Cache.Insert("kategori",dt,null,DateTime.Now.AddMinutes(5),Cache.NoSlidingExpiration);
/* Veriler 5 dakika süreyle ara bellekte saklanacak daha sonra
ise silinecektir.*/
}
/*DataGrid kontrolüne veri kaynağı olarak ara bellekteki
kategori isimli Cache nesnesinin içeriğini veriyoruz. Bunu
yaparken uygun türe dönüştürme işlemini yapıyoruz.*/
DataGrid1.DataSource=(DataTable)Cache["kategori"];
DataGrid1.DataBind();
} |
Uygulamamızda, Northwind veritabanında
yer alan Categories isimli tablodan CategoryName değerlerini çekiyoruz
ve elde ettiğimiz DataTable nesnesini 5 dakika süreyle ara bellekte
tutumak üzere Insert metodu ile Cache nesnesine ekliyoruz. Uygulamayı
ilk çalıştırışımızda aşağıdaki ekran görüntüsünü elde ederiz.

Sayfayı yenilediğimizde veya başka bir
tarayıcı penceresinde tekrardan talep ettiğimizde sürenin düzenli olarak
değiştiğini görürüz. Şimdi 5 dakika dolmadan tablodaki verilerde, örneğin
Beverages alanının değerini [Beverages] olarak değiştirdiğimizi
düşünelim.

Daha sonra sayfayı tekrar çağıralım.

Görüldüğü gibi Beverages değerini
değiştirmemize rağmen yapılan değişiklikler uygulamamıza yansımamıştır.
Bu, verinin ara bellekten Cache nesnesi vasıtasıyla çekildiğinin bir
ispatıdır. Veri ara belleğe alındıktan 5 dakika sonra aynı sayfa tekrar
talep edilir ise bu kez verinin güncel hali ekrana gelecektir. Burada
veriyi Cache nesnesine alırken kullandığımız Insert metodunda Absolute
Expiration (Tam Süre Sonu) zamanı belirlenmiştir. Bu süre, verinin ara
bellekten kesin olarak ne zaman atılacağını söylemektedir. Bununla
birlikte dilersek ara bellekte bulunan veri kümesine olan erişim
sıklığına göre bir Sliding Expiration ( Kayan Süre Sonu ) süreside
belirleyebiliriz. Buna göre,
 |
Ara bellekteki verilere
belirtilen Sliding Expiration ile belirtilen süre zarfında
erişilmez ise bu süre sonunda bellekten atılırlar. Eğer süre
zarfı içinde ara bellekteki verilere sürekli erişiliyorsa
Sliding Expiration süresi geçse dahi veriler ara bellekten
atılmaz ve durumlarını korurlar. |
Sürekli bellekte kalmak deyimi tabiki
sistem kaynakları azalıp ara bellek verileri otomatik olarak atılınca
veya web sunucusu herhangibir neden ile restart olunca geçerli değildir.
Şimdi dilerseniz Sliding Expiration durumunu incelemeye çalışalım. Bunun
için tek yapmamız gereken örneğimizdeki Insert metodunu aşağıdaki ile
değiştirmek olacaktır.
|
Cache.Insert("kategori",dt,null,Cache.NoAbsoluteExpiration,TimeSpan.FromMinutes(3)); |
Olayı daha iyi anlayabilmek için
aşağıdaki şekli inceleyebiliriz.

Sayfa ilk talep edilip veriler ara
belleğa alındığında, Sliding Expiration süresinin 5 dakika ilerisini
gösterecek şekilde ayarlandığını düşünelim. Bu süre dolmadan önce ara
bellekteki veri tekrardan talep edilirse, Cache nesnesinin içeriğinin
boşaltılma süresi şekilden de görüldüğü gibi ilerki bir zamana (o anki
andan 5 dakika sonrasına)
sarkacaktır.
Insert metodunun parametrelerine dikkat
edecek olursanız, ara bellekteki verilerin durumlarının CacheDependency
sınıfına ait nesne örnekleri ile başka bir nesneye bağlı olabileceğini
görürsünüz. Bu bağımılılıkta çoğunlukla fiziki dosyalar göz önüne
alınır. Örneğin, bir XML dosyasındaki veriyi ara belleğe alarak
kullandığımızı düşünelim. Bu veriler pekala güncel haber başlıklarını
veya bir alışveriş sitesindeki ürünlerin kategorilerini gösterebilir. XML dosyasında meydana gelecek olan güncellemeleri anında
ara belleğe yansıtmak için, Cache nesnesini bu XML dosyasına bağımlı
hale getirebiliriz. Şimdi bunun nasıl yapılabileceğini incelemeye
çalışalım. Yukarıda geliştirdiğimiz örneğimizdeki kodlarımızı aşağıdaki
gibi değiştirelim.
Kategoriler.xml dosyasının içeriği;
<?xml version="1.0"
encoding="utf-8" ?>
<Kategoriler>
<Tipi>Muzik CD</Tipi>
<Tipi>Kitap</Tipi>
<Tipi>Film DVD</Tipi>
<Tipi>Muzik DVD</Tipi>
<Tipi>Elektronik Eşyalar</Tipi>
<Tipi>Bilgisayar</Tipi>
<Tipi>Laptop</Tipi>
</Kategoriler> |
default.aspx
private SqlConnection con;
private SqlCommand cmd;
private SqlDataAdapter da;
private DataTable dt;
private DataSet ds;
/*KategoriAlXML metodu Kategoriler.xml dosyası içinden verileri
alır ve DataSet e yükler.*/
private void KategoriAlXML()
{
ds=new DataSet();
ds.ReadXml(Server.MapPath("Kategoriler.xml"));
}
private void Page_Load(object sender, System.EventArgs e)
{
//Güncel saat bilgisini label kontrolüne yazdiriyoruz.
Label1.Text=DateTime.Now.ToLongTimeString();
if(Cache["kategori"]==null)
{
KategoriAlXML();
/* Cache nesnesine DataSet
içerisindeki xml dosyasından okunan içeriğe ait veri kümesi
yüklenir. Bu yükleme işlemi yapılırken bir CacheDependency
nesnesi ile Cache nesnesinin içeriğinin güncelliği belirtilen
XML dosyasına bağlanır.*/
Cache.Insert("kategori",ds.Tables[0],new
CacheDependency(Server.MapPath("Kategoriler.xml")));
}
/*DataGrid kontrolüne veri kaynagi olarak ara bellekteki
kategori isimli Cache nesnesinin içerigini veriyoruz. Bunu
yaparken uygun türe dönüstürme islemini yapiyoruz.*/
DataGrid1.DataSource=(DataTable)Cache["kategori"];
DataGrid1.DataBind();
} |
Burada, Cache nesnesinin içeriğinin
durumunu xml dosyamıza bağlayabilmek için CacheDependency sınıfına ait
bir nesne örneği oluşturulmuştur. Burada CacheDependency sınıfına ait
nesne örneği oluşturulurken yapıcı metoda xml dosyasının sanal adresi
atanmıştır.
| new
CacheDependency(Server.MapPath("Kategoriler.xml")) |
Uygulamamızı çalıştırdığımızda
ilk olarak aşağıdaki ekran görüntüsünü elde ederiz.

Şimdi Kategoriler.xml dosyasının
içeriğinde değişiklik yapalım ve bu değişiklikleri kaydedelim. Örneğin
aşağıdaki gibi bir kaç elemanın bilgisini değştirip yeni bir eleman
ekleyelim.

Bu değişikliklerden sonra sayfayı
tekrardan talep edersek, Cache nesnesinin içerdiği verilerin son yapılan
güncellemelere göre yenilendiğini görürüz. Cache nesnesindeki veriyi bir
dosyaya yukarıdaki gibi bağımlı hale getirdiğimizde, sayfaya yapılan her
talepde dosyanın içeriğinin değişip değişmediği kontrol edilir. Eğer bir
değişiklik var ise, Cache nesnesinin içerdiği veri ara bellekten atılır.
Biz uygulamamızda Cache nesnesini null olup olmadığına göre yükleme
yaptığımız için dosyadaki güncelleme sonucu verinin bu son
halini ara belleğe almış ve DataGrid içeriğini yenilemiş oluruz.

 |
Asp.Net 2.0 da bir Cache
nesnesinin doğrudan Sql Server üzerindeki bir tabloya bağımlı
hale getirilebilmesi ve dolayısıyla veritabanı içindeki bir
tabloda meydan gelecek değişiklilerin Cache nesnesine anında
yanısıtlabilmesi içinde SqlCacheDependency sınıfına ait nesne
örneklerinin kullanılabileceği öngörülmektedir. (* Bu durumu
gelecek görsel derslerimizden birisinde incelemeye çalışacağız.) |
Cache nesnelerinin bellekten atılması
zamana, dosyaya bağlanabileceği gibi, sistem kaynaklarının azalması
durumunda da gerçekleşen bir olaydır. Sistem kaynaklarının azalması ve
ara bellekteki nesnelerin atılması gerektiği durumlarda Cache
nesnelerinin sahip olduğu öncelikler göz önüne alınır. Her ne sebep ile
olursa olsun bir Cache nesnesinin içeriği ara bellekten atıldığında
otomatik olarak çalışmasını istediğimiz metodlar bildirebiliriz. Yani
CallBack metod tekniğini Cache nesneleri içinde kullanabiliriz. Örneğin
ara bellekte tutulan bir nesnenin zaman aşımına uğraması nedeni ile
silindiğinde otomatik olarak callback metodu devreye girerek güncel
halinin tekrardan ara belleğe alınması sağlanabilir. Ya da Cache nesnesi
Remove metodu ile açıkça ara bellekten atıldığı durumlarda CallBack
metodlarını çalıştırabiliriz. Burada bir CallBack metodunun
çağırılabilmesi için, CacheItemRemovedReason temsilcisi
(delegate) tipinden bir nesne örneğinden faydalanılır.
CacheItemRemovedReason temsilcisi aşağıdaki prototipe uyan metodlar
işaret edebilir.
| public delegate void
CacheItemRemovedCallback(string anahtar,object
deger, CacheItemRemovedReason sebep); |
anahtar parametresi Cache nesnesinin
key değerine karşılık gelir. deger parametresi ise ilgili Cache
nesnesinin taşıdığı veriye sahiptir. Son parametre ise
CacheItemRemovedReason numaralandırıcısı (enum sabiti) tipinden bir
değerdir ve CallBack metodunun çağırılma nedenini bir başka deyişle
Cache nesnesinin hangi sebepten dolayı ara bellekten atıldığının
belirlenmesinde kullanılır. CacheItemRemovedReason
numaralandırıcısının sahip olduğu değerler aşağıdaki tabloda
belirtilmektedir.
|
CacheItemRemovedReason
Numaralandırıcı Değeri |
Açıklama |
|
DependencyChanged |
Herhangibir
bağımlılık nedeni ile Cache nesnesinin içeriği ara bellekten
atılmıştır. Örneğin Cache nesnesine bağladığımız XML dosyasında
yapılan bir değişiklik buna neden olabilir. |
| Expired |
Cache nesnesinin
içeriği zaman aşımları nedeni ile ara bellekten atılmıştır. |
| Removed |
Cache nesnesinin
içeriği Remove metodu ile açıkça ara bellekten atılmıştır. Yani
programatik olarak Cache nesnesinin Remove metodu ilgili öğeye
uygulanmıştır. |
| Underused |
Sistem
kaynaklarının azalması sonucunda web sunucusu, Cache
nesnelerinin içeriğini sahip oldukları önem sıralarına göre ara
bellekten atmaya başlamıştır. |
Şimdi CallBack tekniğinin nasıl
uygulandığını basit bir örnek ile incelemeye çalışalım.
private
CacheItemRemovedCallback delCallBack=null;
private SqlConnection con;
private SqlCommand cmd;
private SqlDataAdapter da;
private DataTable dt;
private static string m_Sebep;
private static bool m_Durum=false;
private void KategorileriAl()
{
con=new SqlConnection("data source=BURKI;initial
catalog=Northwind;integrated security=SSPI");
cmd=new SqlCommand("SELECT DISTINCT CategoryName FROM
Categories",con);
da=new SqlDataAdapter(cmd);
dt=new DataTable();
da.Fill(dt);
}
private void GeriBildirimMetodu(string anahtar,object
deger,CacheItemRemovedReason sebep)
{
m_Sebep=sebep.ToString();
m_Durum=true;
}
private void btnRemove_Click(object sender, System.EventArgs e)
{
if(Cache["Nesne1"]!=null)
{
Cache.Remove("Nesne1");
}
}
private void btnCacheEkle_Click(object sender, System.EventArgs
e)
{
delCallBack=new
CacheItemRemovedCallback(this.GeriBildirimMetodu);
if(Cache["Nesne1"]==null)
{
KategorileriAl();
Cache.Insert("Nesne1",dt,null,DateTime.Now.AddSeconds(10),Cache.NoSlidingExpiration,CacheItemPriority.High,delCallBack);
m_Durum=false;
}
}
private void WebForm1_PreRender(object sender, System.EventArgs
e)
{
DataGrid1.DataSource=Cache["Nesne1"];
DataGrid1.DataBind();
if(m_Durum)
lblDurum.Text=m_Sebep;
else
lblDurum.Text="";
} |
Yukardaki örnekte, Cache nesnesine
DataTable içeriğini eklerken Insert metodunun aşağıdaki versiyonu
kullanılmıştır.
|
Cache.Insert("Nesne1",dt,null,DateTime.Now.AddSeconds(10),Cache.NoSlidingExpiration,CacheItemPriority.High,delCallBack); |
Burada delCallBack, CallBack metodumuz
olan GeriBildirimMetodunu işaret eden CacheItemRemovedCallback
tipindeki temsilcimidir. Kullanıcı Remove işlemini gerçekleştirdiğinde
veya Cache nesnesi zaman aşımı nedeni ile ara bellekten atıldığında,
geri bildirim metodu çalışacaktır. Örneğimizi çalıştırdığımızda ve 10
saniyelik zaman aşımı süresi dolmadan Ekle ve daha sonra Çıkart başlıklı
butonlara tıkladığımızda aşağıdaki ekran görüntüsünü elde ederiz.

Eğer 10 saniye süresi dolduktan sonra
Çıkart başlıklı butona basarsak Remove metodu çalıştırılmayacak ancak
geri bildirim metodumuz çalışarak nesnenin ara bellekten atılma nedeni
Expired olarak değişecektir.

CallBack tekniğinin uygulanışını daha
iyi kavrayabilmek için, örnekleri debug modunda çalıştırıp breakpoint
ler vasıtısayıla kodları izlemenizi öneririm. Böylece geldik bir
makalemizin daha sonuna. Bir sonraki makalemizde görüşmek dileğiyle
hepinize mutlu günler dilerim.
Örnek
uygulama için tıklayın.
Burak Selim ŞENYURT
selim@bsenyurt.com
Makale:
Caching Mekanizmasını Anlamak - 2 ASP.NET Burak Selim Şenyurt
|
|
HAZ 20
2007 |
Süper makale.
Oracle için CacheDependency makalesini dört gözle bekliyoruz.
Tekrar teşekkürler... |
|
|
Sayfalar :
|
|
|
|
|
|
|
-
-
Eklenen Son 10
-
Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
|
|
|
|