Uygulama Başlangıcında Verileri Önbelleğe Alma (C#)
tarafından Scott Mitchell
Herhangi bir Web uygulamasında bazı veriler sık kullanılır ve bazı veriler seyrek kullanılır. Önbelleğe Alma olarak bilinen bir teknik olan sık kullanılan verileri önceden yükleyerek ASP.NET uygulamamızın performansını geliştirebiliriz. Bu öğreticide, uygulama başlangıcında önbelleğe veri yüklemek için proaktif yükleme yaklaşımı gösterilmektedir.
Giriş
Önceki iki öğreticide, Sunu ve Önbelleğe Alma Katmanlarındaki verileri önbelleğe alma işlemine bakmıştım. ObjectDataSource ile Verileri Önbelleğe Alma bölümünde, Sunu Katmanı'ndaki verileri önbelleğe almak için ObjectDataSource'un önbelleğe alma özelliklerini kullanmayı inceledik. Mimarideki Verileri Önbelleğe Alma , önbelleğe alma işlemini yeni, ayrı bir Önbelleğe Alma Katmanında inceledi. Bu öğreticilerin her ikisi de veri önbelleğiyle çalışırken reaktif yüklemeyi kullandı. Reaktif yükleme ile, veriler her istenişinde sistem ilk olarak önbellekte olup olmadığını denetler. Aksi takdirde, veritabanı gibi kaynak kaynaktan verileri alır ve önbellekte depolar. Reaktif yüklemenin temel avantajı, uygulama kolaylığıdır. Dezavantajlarından biri, istekler arasında eşit olmayan performansıdır. Ürün bilgilerini görüntülemek için önceki öğreticide yer alan Önbelleğe Alma Katmanı'nı kullanan bir sayfa düşünün. Bu sayfa ilk kez ziyaret edildiğinde veya önbelleğe alınan veriler bellek kısıtlamaları nedeniyle çıkarıldıktan veya belirtilen süre sonu ulaşıldıktan sonra ilk kez ziyaret edildiğinde, verilerin veritabanından alınması gerekir. Bu nedenle, bu kullanıcı istekleri önbellek tarafından sunulan kullanıcı isteklerinden daha uzun sürer.
Proaktif yükleme , önbelleğe alınan verileri ihtiyaç duyulmadan yükleyerek istekler arasındaki performansı düzelten alternatif bir önbellek yönetimi stratejisi sağlar. Genellikle proaktif yükleme, temel alınan verilerde bir güncelleştirme olduğunda düzenli aralıklarla denetlenen veya bildirim alan bazı işlemler kullanır. Bu işlem daha sonra önbelleği güncel tutmak için güncelleştirir. Temel alınan veriler yavaş veritabanı bağlantısından, Web hizmetinden veya özellikle yavaş veri kaynaklarından geliyorsa proaktif yükleme özellikle yararlıdır. Ancak, değişiklikleri denetlemek ve önbelleği güncelleştirmek için bir işlem oluşturmayı, yönetmeyi ve dağıtmayı gerektirdiğinden, proaktif yükleme yaklaşımının uygulanması daha zordur.
Proaktif yüklemenin bir diğer özelliği ve bu öğreticide keşfedeceğimiz tür, verileri uygulama başlangıcında önbelleğe yüklemektir. Bu yaklaşım özellikle veritabanı arama tablolarındaki kayıtlar gibi statik verileri önbelleğe almak için kullanışlıdır.
Not
Proaktif ve reaktif yükleme arasındaki farkların yanı sıra artılar, dezavantajlar ve uygulama önerileri listelerine daha ayrıntılı bir bakış için, .NET Framework Uygulamaları için Önbelleğe Alma Mimarisi Kılavuzu'nun Önbellekİçeriğini Yönetme bölümüne bakın.
1. Adım: Uygulama Başlangıcında Önbelleğe Alınacak Verileri Belirleme
Önceki iki öğreticide incelediğimiz reaktif yükleme kullanan önbelleğe alma örnekleri, düzenli aralıklarla değişebilen ve oluşturulması çok uzun sürmeyen verilerle iyi çalışır. Ancak önbelleğe alınan veriler hiçbir zaman değişmezse, reaktif yükleme tarafından kullanılan süre sonu gereksizdir. Benzer şekilde, önbelleğe alınan verilerin oluşturulması çok uzun sürüyorsa, istekleri önbelleği boş bulayan kullanıcıların, temel alınan veriler alınırken uzun bir bekleme süresine dayanması gerekir. Uygulama başlangıcında oluşturulması son derece uzun süren statik verileri ve verileri önbelleğe almayı göz önünde bulundurun.
Veritabanlarında birçok dinamik, sık değişen değer olsa da, çoğu düzgün miktarda statik veriye sahiptir. Örneğin, neredeyse tüm veri modellerinde sabit bir seçim kümesinden belirli bir değer içeren bir veya daha fazla sütun vardır. Veritabanı Patients
tablosunda, değer kümesi İngilizce, İspanyolca, Fransızca, Rusça, Japonca vb. olabilen bir PrimaryLanguage
sütun olabilir. Bu tür sütunlar genellikle arama tabloları kullanılarak uygulanır. İngilizce veya Fransızca Patients
dizesini tabloda depolamak yerine, genellikle iki sütunu (benzersiz tanımlayıcı ve dize açıklaması) ve her olası değer için bir kaydı olan ikinci bir tablo oluşturulur. PrimaryLanguage
Tablodaki sütun, Patients
arama tablosunda karşılık gelen benzersiz tanımlayıcıyı depolar. Şekil 1'de hasta John Doe'nun birincil dili İngilizce, Ed Johnson'ınki ise Rusça'dır.
Şekil 1: Tablo, Languages
Tablo Tarafından Patients
Kullanılan Bir Arama Tablosudur
Yeni bir hastayı düzenlemek veya oluşturmak için kullanıcı arabirimi, tablodaki Languages
kayıtlar tarafından doldurulan izin verilebilen dillerin bir açılan listesini içerir. Önbelleğe alma olmadan, bu arabirim her ziyaretinde sistemin tabloyu sorgulaması Languages
gerekir. Arama tablosu değerleri çok seyrek değiştiğinden (varsa) bu gereksiz ve gereksizdir.
Önceki öğreticilerde incelenen aynı reaktif yükleme tekniklerini kullanarak verileri önbelleğe Languages
alabilirdik. Ancak reaktif yükleme, statik arama tablosu verileri için gerekli olmayan zamana bağlı bir süre sonu kullanır. Reaktif yükleme kullanarak önbelleğe almak hiç önbelleğe almamaktan daha iyi olsa da, en iyi yaklaşım arama tablosu verilerini uygulama başlangıcında önceden önbelleğe yüklemektir.
Bu öğreticide arama tablosu verilerinin ve diğer statik bilgilerin nasıl önbelleğe alınacağını inceleyeceğiz.
2. Adım: Verileri Önbelleğe Almanın Farklı Yollarını inceleme
Bilgiler, çeşitli yaklaşımlar kullanılarak ASP.NET bir uygulamada program aracılığıyla önbelleğe alınabilir. Önceki öğreticilerde veri önbelleğinin nasıl kullanılacağını zaten görmüştük. Alternatif olarak, nesneler statik üyeler veya uygulama durumu kullanılarak program aracılığıyla önbelleğe alınabilir.
Bir sınıfla çalışırken, genellikle üyelerine erişilmeden önce sınıfın örneği oluşturulmalıdır. Örneğin, İş Mantığı Katmanımızdaki sınıflardan birinden bir yöntemi çağırmak için önce sınıfının bir örneğini oluşturmamız gerekir:
ProductsBLL productsAPI = new ProductsBLL();
productsAPI.SomeMethod();
productsAPI.SomeProperty = "Hello, World!";
SomeMethod'u çağırabilmek veya SomeProperty ile çalışabilmek için önce anahtar sözcüğünü kullanarak sınıfının bir örneğini new
oluşturmamız gerekir. SomeMethod ve SomeProperty belirli bir örnekle ilişkilendirilir. Bu üyelerin yaşam süresi, ilişkili nesnenin ömrüne bağlıdır. Diğer taraftan statik üyeler, sınıfın tüm örnekleri arasında paylaşılan değişkenler, özellikler ve yöntemlerdir ve sonuç olarak, sınıfı kadar uzun bir yaşam süresine sahiptir. Statik üyeler anahtar sözcüğüyle static
belirtilir.
Statik üyelere ek olarak, veriler uygulama durumu kullanılarak önbelleğe alınabiliyor. Her ASP.NET uygulama, uygulamanın tüm kullanıcıları ve sayfaları arasında paylaşılan bir ad/değer koleksiyonu tutar. Bu koleksiyona sınıfınHttpContext
Application
özelliği kullanılarak erişilebilir ve aşağıdaki gibi bir ASP.NET sayfasının arkadaki kod sınıfından kullanılabilir:
Application["key"] = value;
object value = Application["key"];
Veri önbelleği verileri önbelleğe almak için çok daha zengin bir API sağlar, zaman ve bağımlılık tabanlı süre sonu, önbellek öğesi öncelikleri vb. için mekanizmalar sağlar. Statik üyeler ve uygulama durumu ile bu tür özelliklerin sayfa geliştiricisi tarafından el ile eklenmesi gerekir. Ancak, uygulamanın ömrü boyunca uygulama başlangıcında verileri önbelleğe alırken, veri önbelleğinin avantajları moot'tır. Bu öğreticide, statik verileri önbelleğe almak için üç tekniği de kullanan kodu inceleyeceğiz.
3. Adım: Tablo Verilerini Önbelleğe AlmaSuppliers
Bugüne kadar uyguladığımız Northwind veritabanı tablolarında geleneksel arama tablosu yok. DAL tüm model tablolarımızda uygulanan ve değerleri statik olmayan dört DataTable. Dal'a yeni bir DataTable ve ardından BLL'ye yeni bir sınıf ve yöntemler eklemek için zaman harcamak yerine, bu öğretici için tablonun verilerinin Suppliers
statik olduğunu varsayalım. Bu nedenle, bu verileri uygulama başlangıcında önbelleğe alabilirdik.
Başlamak için klasöründe adlı StaticCache.cs
CL
yeni bir sınıf oluşturun.
Şekil 2: Klasörde Sınıf CL
Oluşturma StaticCache.cs
Başlangıçtaki verileri uygun önbellek deposuna yükleyen bir yöntemin yanı sıra bu önbellekten veri döndüren yöntemler eklemeliyiz.
[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;
}
}
Yukarıdaki kod, suppliers
sınıfın GetSuppliers()
yönteminden çağrılan LoadStaticCache()
yönteminin SuppliersBLL
sonuçlarını tutmak için statik üye değişkeni kullanır. LoadStaticCache()
yöntemi, uygulamanın başlatılması sırasında çağrılmaya yöneliktir. Bu veriler uygulama başlangıcında yüklendikten sonra, sağlayıcı verileriyle çalışması gereken tüm sayfalarda sınıfın StaticCache
GetSuppliers()
yöntemi çağrılır. Bu nedenle, tedarikçileri almak için veritabanına yapılan çağrı, uygulama başlangıcında yalnızca bir kez gerçekleşir.
Önbellek deposu olarak statik üye değişkeni kullanmak yerine alternatif olarak uygulama durumunu veya veri önbelleğini kullanmış olabilirdik. Aşağıdaki kod, uygulama durumunu kullanmak için yeniden kullanılan sınıfı gösterir:
[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;
}
}
içinde LoadStaticCache()
, sağlayıcı bilgileri uygulama değişkeni anahtarına depolanır. 'den GetSuppliers()
uygun tür (Northwind.SuppliersDataTable
) olarak döndürülür. uygulama durumuna kullanılarak ASP.NET sayfaların Application["key"]
arka kod sınıflarında erişilebilirken, geçerli HttpContext
öğesini almak için mimaride kullanmamız HttpContext.Current.Application["key"]
gerekir.
Benzer şekilde, aşağıdaki kodda gösterildiği gibi veri önbelleği önbellek deposu olarak kullanılabilir:
[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;
}
}
Zaman tabanlı süre sonu olmadan veri önbelleğine öğe eklemek için giriş parametreleri olarak ve System.Web.Caching.Cache.NoSlidingExpiration
değerlerini kullanınSystem.Web.Caching.Cache.NoAbsoluteExpiration
. Önbellek öğesinin önceliğini belirtebilmemiz için veri önbelleğinin Insert
yönteminin bu özel aşırı yüklemesi seçildi. Kullanılabilir bellek yetersiz çalıştığında önbellekten hangi öğelerin atılabileceğini belirlemek için öncelik kullanılır. Burada, bu önbellek öğesinin atılmamasını sağlayan önceliğini NotRemovable
kullanırız.
Not
Bu öğreticinin indirme işlemi, statik üye değişkeni yaklaşımını kullanarak sınıfını uygular StaticCache
. Uygulama durumu ve veri önbelleği tekniklerinin kodu, sınıf dosyasındaki açıklamalarda kullanılabilir.
4. Adım: Uygulama Başlangıcında Kod Yürütme
Bir web uygulaması ilk başlatıldığında kodu yürütmek için adlı Global.asax
özel bir dosya oluşturmamız gerekir. Bu dosya uygulama, oturum ve istek düzeyi olayları için olay işleyicileri içerebilir ve burada uygulama başlatıldığında yürütülecek kodu ekleyebiliriz.
Global.asax
Visual Studio'nun Çözüm Gezgini web sitesi proje adına sağ tıklayıp Yeni Öğe Ekle'yi seçerek dosyayı web uygulamanızın kök dizinine ekleyin. Yeni Öğe Ekle iletişim kutusunda Genel Uygulama Sınıfı öğe türünü seçin ve ekle düğmesine tıklayın.
Not
Projenizde zaten bir Global.asax
dosya varsa, Genel Uygulama Sınıfı öğe türü Yeni Öğe Ekle iletişim kutusunda listelenmez.
Şekil 3: Dosyayı Web Uygulamanızın Global.asax
Kök Dizinine Ekleme (Tam boyutlu görüntüyü görüntülemek için tıklayın)
Varsayılan Global.asax
dosya şablonu, sunucu tarafı <script>
etiketinde beş yöntem içerir:
Application_Start
web uygulaması ilk kez başlatıldığında yürütülürApplication_End
uygulama kapatılırken çalışırApplication_Error
, işlenmeyen bir özel durum uygulamaya her ulaştığında yürütülürSession_Start
yeni bir oturum oluşturulduğunda yürütülürSession_End
oturumun süresi dolduğunda veya bırakıldığında çalışır
Olay Application_Start
işleyicisi, uygulamanın yaşam döngüsü sırasında yalnızca bir kez çağrılır. Uygulama, uygulamadan ilk kez bir ASP.NET kaynağı istendiği zaman başlatılır ve uygulama yeniden başlatılana kadar çalışmaya devam eder. Bu işlem klasörün içeriğini /Bin
değiştirerek, değiştirerek Global.asax
, klasördeki App_Code
içeriği değiştirerek veya dosyayı diğer nedenlerle değiştirebilir Web.config
. Uygulama yaşam döngüsü hakkında daha ayrıntılı bir tartışma için ASP.NET Uygulama Yaşam Döngüsüne Genel Bakış'a bakın.
Bu öğreticiler için yalnızca yöntemine Application_Start
kod eklememiz gerekir, bu nedenle diğerlerini kaldırmaktan çekinmeyin. içindeApplication_Start
, sağlayıcı bilgilerini yükleyip önbelleğe alacak sınıfın LoadStaticCache()
yöntemini çağırmanız StaticCache
yeterlidir:
<%@ Application Language="C#" %>
<script runat="server">
void Application_Start(object sender, EventArgs e)
{
StaticCache.LoadStaticCache();
}
</script>
İşte bu kadar! Uygulama başlangıcında yöntemi, LoadStaticCache()
sağlayıcı bilgilerini BLL'den alır ve statik üye değişkeninde (veya sınıfında kullandığınız StaticCache
önbellek deposunda) depolar. Bu davranışı doğrulamak için yönteminde Application_Start
bir kesme noktası ayarlayın ve uygulamanızı çalıştırın. Uygulama başlatılırken kesme noktasına isabet ettiğini unutmayın. Ancak sonraki istekler yönteminin yürütülmesine Application_Start
neden olmaz.
Şekil 4: Olay İşleyicisinin Application_Start
Yürütülmekte Olduğunu Doğrulamak için Kesme Noktası Kullanma (Tam boyutlu görüntüyü görüntülemek için tıklayın)
Not
Hata ayıklamaya Application_Start
ilk başladığınızda kesme noktasına ulaşmazsanız, bunun nedeni uygulamanızın zaten başlatılmış olmasıdır. veya Web.config
dosyalarınızı değiştirerek Global.asax
uygulamayı yeniden başlatmaya zorlayın ve sonra yeniden deneyin. Uygulamayı hızlı bir şekilde yeniden başlatmak için bu dosyalardan birinin sonuna boş bir satır eklemeniz (veya kaldırmanız) yeterlidir.
5. Adım: Önbelleğe Alınan Verileri Görüntüleme
Bu noktada sınıfı, StaticCache
uygulama başlangıcında önbelleğe alınan sağlayıcı verilerinin yöntemi aracılığıyla erişilebilen bir sürümüne GetSuppliers()
sahiptir. Sunu Katmanındaki bu verilerle çalışmak için ObjectDataSource kullanabilir veya bir ASP.NET sayfasının arkadaki kod sınıfından sınıfın GetSuppliers()
yöntemini program aracılığıyla çağırabilirizStaticCache
. Önbelleğe alınan sağlayıcı bilgilerini görüntülemek için ObjectDataSource ve GridView denetimlerini kullanmaya göz atalım.
Başlangıç olarak klasördeki sayfayı AtApplicationStartup.aspx
Caching
açın. Bir GridView'u Toolbox'tan tasarımcıya sürükleyerek özelliğini olarak Suppliers
ayarlayınID
. Ardından GridView'un akıllı etiketinden adlı SuppliersCachedDataSource
yeni bir ObjectDataSource oluşturmayı seçin. Sınıfın yöntemini kullanmak StaticCache
için ObjectDataSource'ı GetSuppliers()
yapılandırın.
Şekil 5: ObjectDataSource'un Sınıfını kullanacak şekilde yapılandırılması StaticCache
(Tam boyutlu görüntüyü görüntülemek için tıklayın)
Şekil 6: Önbelleğe Alınan Sağlayıcı Verilerini Almak için Yöntemini Kullanma GetSuppliers()
(Tam boyutlu görüntüyü görüntülemek için tıklayın)
Sihirbazı tamamladıktan sonra, Visual Studio içindeki her veri alanı SuppliersDataTable
için otomatik olarak BoundFields ekler. GridView ve ObjectDataSource'unuzun bildirim temelli işaretlemesi aşağıdakine benzer olmalıdır:
<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" />
Şekil 7'de, bir tarayıcı üzerinden görüntülendiğinde sayfa gösterilir. BLL'nin SuppliersBLL
sınıfından veri çektiğimizde çıkış aynıdır, ancak sınıfı kullanıldığında StaticCache
sağlayıcı verileri uygulama başlangıcında önbelleğe alınmış olarak döndürülüyor. Bu davranışı doğrulamak için sınıfın GetSuppliers()
yönteminde StaticCache
kesme noktaları ayarlayabilirsiniz.
Şekil 7: Önbelleğe Alınan Sağlayıcı Verileri GridView'da Görüntülenir (Tam boyutlu görüntüyü görüntülemek için tıklayın)
Özet
Her veri modelinin çoğu, genellikle arama tabloları biçiminde uygulanan makul miktarda statik veri içerir. Bu bilgiler statik olduğundan, bu bilgilerin her görüntülenmesi gerektiğinde veritabanına sürekli olarak erişmek için bir neden yoktur. Ayrıca, statik yapısı nedeniyle verileri önbelleğe alırken süre sonu gerekmez. Bu öğreticide bu tür verilerin nasıl alındığını ve veri önbelleğinde, uygulama durumunda ve statik üye değişkeni aracılığıyla nasıl önbelleğe alındığını gördük. Bu bilgiler uygulama başlangıcında önbelleğe alınır ve uygulamanın ömrü boyunca önbellekte kalır.
Bu öğreticide ve son iki öğreticide, uygulamanın kullanım ömrü boyunca verileri önbelleğe alma ve zamana bağlı süre sonu kullanma konularını inceledik. Ancak veritabanı verilerini önbelleğe alırken zamana bağlı süre sonu idealden daha az olabilir. Önbelleği düzenli aralıklarla boşaltmak yerine, önbelleğe alınan öğeyi yalnızca temel alınan veritabanı verileri değiştirildiğinde çıkarmak en uygun olacaktır. Bu ideal, sonraki öğreticimizde inceleyeceğimiz SQL önbellek bağımlılıklarının kullanımıyla mümkündür.
Mutlu Programlama!
Yazar hakkında
Yedi ASP/ASP.NET kitabının yazarı ve 4GuysFromRolla.com kurucusu Scott Mitchell, 1998'den beri Microsoft Web teknolojileriyle çalışmaktadır. Scott bağımsız bir danışman, eğitmen ve yazar olarak çalışmaktadır. Son kitabı Sams Teach Yourself ASP.NET 24 Hours 2.0'dır. Adresine adresinden veya adresinden ulaşabileceğiniz http://ScottOnWriting.NETblogu aracılığıyla ulaşabilirsinizmitchell@4GuysFromRolla.com.
Özel Teşekkürler
Bu öğretici serisi birçok yararlı gözden geçiren tarafından gözden geçirildi. Bu öğreticinin baş gözden geçirenleri Arasında Teresa Murphy ve Zack Jones vardı. Yaklaşan MSDN makalelerimi gözden geçirmek istiyor musunuz? Öyleyse, bana adresinden bir satır mitchell@4GuysFromRolla.combırakın.
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin