System.Runtime.Caching.MemoryCache ve HttpRuntime.Cache - herhangi bir fark var mı?


85

ASP.NET MVC projelerinde hangisi tercih edilir MemoryCacheve arasında fark var mı merak ediyorum HttpRuntime.Cache?

Anladığım kadarıyla, her ikisi de iş parçacığı için güvenli, API ilk bakışta aşağı yukarı aynı, yani hangisinin ne zaman kullanılacağı konusunda herhangi bir fark var mı?

Yanıtlar:


82

HttpRuntime.CacheCachemevcut uygulamanın kodunu alır .

MemoryCacheSınıf ASP.NET benzer Cachesınıfın.

MemoryCacheSınıf birçok özellikleri ve ASP.NET kullandıysanız size tanıdık gelecektir önbellek erişmek için yöntemleri vardır Cachesınıfı.

Arasındaki temel fark HttpRuntime.Cacheve MemoryCacheikincisi ASP.NET uygulamaları değildir .NET Framework uygulamaları tarafından kullanılabilmesi için değiştirildi olmasıdır.

Ek okuma için:

Güncelleme :

Kullanıcıların geri bildirimlerine göre bazen Jon davis blogu çalışmıyor, bu yüzden yazının tamamını resim olarak koydum, lütfen bakın.

Not: Eğer net değilse, resmin üzerine tıklamanız yeterlidir, daha sonra bir tarayıcıda açılacaktır ve yakınlaştırmak için tekrar tıklayın :)

görüntü açıklamasını buraya girin


Bu John Davis makalesi gerçekten iyi okunuyor - tek bir yerde net artılar ve eksiler.
Giedrius

kesinlikle her şey tek bir yerde. iyi bir. Davis ayrıca 4 farklı önbellekleme yönteminden de bahsetti.
Sampath

2
@Spikeh Benim için iyi yükleniyor.
user247702

1
@Stijn Teşekkürler, geçen gün yüklenmiyordu, ama şimdi geri döndü :)
Spikeh

1
@sampath şimdi çalışıyor. Dün site saldırıya uğramış gibi görünüyordu. Yardımınız için teşekkürler!
Baga

25

İşte Jon Davis'in makalesi. Okunabilirliği korumak için, artık kullanılmayan EntLib bölümünü, girişi ve sonucu kesiyorum.


ASP.NET Önbelleği

ASP.NET veya System.Web.dll derlemesinin bir önbelleğe alma mekanizması vardır. Asla bir web bağlamının dışında kullanılması amaçlanmamıştır, ancak web dışında kullanılabilir ve yukarıdaki tüm sona erme davranışlarını bir tür hashtable içinde gerçekleştirir.

Google'ı araştırdıktan sonra, .NET'teki yerleşik önbelleğe alma işlevini tartışan pek çok kişinin web dışı projelerinde ASP.NET önbelleğini kullanmaya başvurduğu görülüyor. Bu artık .NET'te en çok bulunan, en çok desteklenen yerleşik önbelleğe alma sistemi değildir; .NET 4'te daha sonra gireceğim bir ObjectCache var. Microsoft, ASP.NET önbelleğinin web dışında kullanılmak üzere tasarlanmadığı konusunda her zaman kararlı olmuştur. Ancak birçok kişi hala .NET 2.0 ve .NET 3.5'te sıkışmış durumda ve üzerinde çalışacak bir şeye ihtiyaç duyuyor ve MSDN açıkça şunu söylese de bu birçok kişi için işe yarıyor:

Not: Cache sınıfı, ASP.NET uygulamalarının dışında kullanılmak üzere tasarlanmamıştır. Web uygulamaları için önbelleğe alma sağlamak için ASP.NET'te kullanılmak üzere tasarlanmış ve test edilmiştir. Konsol uygulamaları veya Windows Forms uygulamaları gibi diğer türden uygulamalarda, ASP.NET önbelleğe alma düzgün çalışmayabilir.

ASP.NET önbelleğinin sınıfı, System.Web.dll'deki System.Web.Caching.Cache'dir. Ancak, bir Cache nesnesini basitçe yenileyemezsiniz. Bunu System.Web.HttpRuntime.Cache'den edinmelisiniz.

Cache cache = System.Web.HttpRuntime.Cache;

ASP.NET önbelleğiyle çalışma, burada MSDN'de belgelenmiştir .

Artıları:

  1. Bu oluyor yerleşik .
  2. .NET 1.0 sözdizimine rağmen, kullanımı oldukça basittir .
  3. Web bağlamında kullanıldığında, iyi test edilmiştir . Web bağlamları dışında, Google aramalarına göre, Microsoft'un aleyhine önermesine rağmen, .NET 2.0 veya sonraki bir sürümünü kullandığınız sürece sorunlara neden olduğu yaygın olarak bilinmemektedir.
  4. Sen edilebilir bildirilir hayatta tutmak gerekiyor ve önceden öğesinin önceliğini ayarlamak olamazdı eğer gerekli bir öğe kaldırılır Bir temsilci aracılığıyla.
  5. Tek tek öğeler , bu makalenin başındaki kaldırma yöntemleri listesinde yer alan (a), (b) veya (c) son kullanma ve kaldırma yöntemlerinden herhangi birinin esnekliğine sahiptir. Ayrıca sona erme davranışını fiziksel bir dosyanın varlığı ile ilişkilendirebilirsiniz.

Eksileri:

  1. Sadece durağan değil, sadece bir tane var . Kendi statik önbellek örneğiyle kendi türünüzü oluşturamazsınız. Tüm uygulamanız için yalnızca bir gruba sahip olabilirsiniz. Kovayı, anahtarlarda ön eklerin eklenmesi gibi şeyler yapan kendi sarmalayıcılarınızla sarabilir ve anahtar / değer çiftlerini geri çektiğinizde bu önekleri kaldırabilirsiniz. Ama hala tek bir kova var. Her şey bir araya toplanmış. Örneğin, üç veya dört farklı türde veriyi ayrı ayrı önbelleğe alması gereken bir hizmetiniz varsa, bu gerçek bir sıkıntı olabilir. Acınacak kadar basit projeler için bu büyük bir sorun olmamalı. Ancak, bir projenin gereksinimleri nedeniyle herhangi bir önemli düzeyde karmaşıklığı varsa, ASP.NET önbelleği genellikle yeterli olmaz.
  2. Öğeler ister istemez kaybolabilir. Pek çok insan bunun farkında değil - bu önbellek uygulaması hakkındaki bilgilerimi tazeleyene kadar farkında değildim. Varsayılan olarak, ASP.NET önbelleği, kendisi gibi "hissettiğinde" öğeleri yok etmek için tasarlanmıştır. Daha spesifik olarak, bu makalenin başındaki önbellek tablosu tanımımda (c) kısmına bakın. Aynı süreçteki başka bir iş parçacığı tamamen farklı bir şey üzerinde çalışıyorsa ve yüksek öncelikli öğeleri önbelleğe atıyorsa, o zaman .NET biraz belleğe ihtiyaç duyması gerektiğine karar verir vermez önbellekteki bazı öğeleri, öncelikleri, önce daha düşük öncelikler. Önbellek öğeleri eklemek için burada belgelenen tüm örnekler, bellek temizleme amacıyla kaldırılmasını engelleyen NotRemovable öncelik değeri yerine varsayılan önceliği kullanır, ancak yine de süre sonu ilkesine göre kaldırır.
  3. Anahtar bir dizge olmalıdır. Örneğin, kayıtların uzun veya tam sayıya dayalı olduğu veri kayıtlarını önbelleğe alıyorsanız, önce anahtarı bir dizeye dönüştürmeniz gerekir.
  4. Sözdizimi bayat . ArrayList veya Hashtable'dan bile daha çirkin olan .NET 1.0 sözdizimidir. Burada jenerik yok, IDictionary <> arayüzü yok. Contains () yöntemi yoktur, Anahtar koleksiyonu yoktur, standart olay yoktur; yalnızca bir Get () yöntemine ve Get () ile aynı şeyi yapan, eşleşme yoksa boş döndüren bir dizinleyiciye ve ayrıca Add (), Insert () (fazlalık?), Remove () ve GetEnumerator () .
  5. Varsayılan sona erme / kaldırma davranışlarınızı kurmaya yönelik KURU ilkesini yok sayar, böylece bunları unutabilirsiniz. Önbelleğe, her öğe eklediğinizde eklediğiniz öğenin süresinin nasıl dolmasını veya kaldırılmasını istediğinizi açıkça belirtmeniz gerekir.
  6. Önbelleğe alınan bir öğenin, eklendiği zamanın zaman damgası gibi önbelleğe alma ayrıntılarına erişmenin bir yolu yoktur . Kapsülleme burada biraz abartıldı ve önbelleğe alınmış bir öğenin başka bir önbelleğe alma mekanizmasına (yani oturum toplama) karşı geçersiz kılınması gerekip gerekmediğini belirlemeye çalışırken kodda önbelleği kullanmayı zorlaştırdı.
  7. Kaldırma olayları , olay olarak gösterilmez ve eklenme sırasında izlenmelidir.
  8. Ve yeterince söylemediysem, Microsoft açık bir şekilde web dışında buna karşı öneride bulunuyor . Ve eğer .NET 1.1 ile lanetlendiyseniz , onu web dışında herhangi bir kararlılıkla kullanmamalısınız, bu yüzden zahmet etmeyin.

.NET 4.0'ın ObjectCache / MemoryCache

Microsoft nihayet .NET Framework'ün en son sürümünde soyut bir ObjectCache sınıfı ve web dışı bir ortamda bellek içi amaçlar için ObjectCache'yi devralan ve uygulayan bir MemoryCache uygulaması gerçekleştirdi.

System.Runtime.Caching.ObjectCache, System.Runtime.Caching.dll derlemesindedir. ASP.NET önbelleğinde bulunan temelde aynı .NET 1.0 stili arabirimlerini bildiren soyut bir sınıftır. System.Runtime.Caching.MemoryCacheObjectCache'nin bellek içi uygulamasıdır ve birkaç değişiklikle ASP.NET önbelleğine çok benzer.

Kayan bir son kullanma tarihine sahip bir öğe eklemek için kodunuz aşağıdaki gibi görünecektir:

var config = new NameValueCollection();  
var cache = new MemoryCache("myMemCache", config);  
cache.Add(new CacheItem("a", "b"),  
    new CacheItemPolicy  
    {  
        Priority = CacheItemPriority.NotRemovable,  
        SlidingExpiration=TimeSpan.FromMinutes(30)  
    }); 

Artıları:

  1. Yerleşiktir ve artık Microsoft tarafından web dışında desteklenmekte ve önerilmektedir.
  2. ASP.NET önbelleğinden farklı olarak, bir MemoryCache nesnesi örneğini başlatabilirsiniz.

    Not: Statik olması gerekmez, ancak olması gerekir — bu Microsoft'un önerisidir (bkz. Sarı Dikkat) .

  3. Öğeler eklendiğinde, gereksiz Insert () kaldırıldığında, öğeler bir CacheItem ile eklenebilirken, kaldırma olaylarına abone olma yeteneği gibi ASP.NET önbelleğinin arabirimine göre birkaç küçük iyileştirme yapılmıştır. önbelleğe alma stratejisini tanımlayan bir başlatıcıya sahip nesne ve İçerir () eklendi.

Eksileri:

  1. Yine de KURU'yu tam olarak güçlendirmiyor. Benim küçük deneyimlerime göre, kayan süre sonu TimeSpan'ı bir kez ayarlayıp unutamazsınız. Ve açıkçası, yukarıdaki öğe ekleme örneğindeki politika daha okunaklı olsa da, korkunç ayrıntılar gerektiriyor.
  2. Halen jenerik olarak anahtarlanmamıştır; anahtar olarak bir dizge gerektirir. Dolayısıyla, dizeye dönüştürmediğiniz sürece veri kayıtlarını önbelleğe alıyorsanız, uzun veya int depolayamazsınız.

Kendin Yap: Kendin Yap

Açık veya kayan süre sonu gerçekleştiren bir önbelleğe alma sözlüğü oluşturmak aslında oldukça basittir. (Bellek temizleme amacıyla öğelerin otomatik olarak kaldırılmasını istiyorsanız, çok daha zor hale gelir.) Yapmanız gereken tek şey:

  1. T türü bir değer içerecek Expiring veya Expirable gibi bir şey, değer önbelleğe eklendiğinde saklanacak DateTime türünde bir TimeStamp özelliği ve zaman damgasından ne kadar uzakta olduğunu gösteren bir TimeSpan oluşturun. öğenin süresi dolmalıdır. Açık bir süre sonu için, zaman damgası tarafından çıkarılan bir tarihe verilen TimeSpan'ı ayarlayan bir özellik ayarlayıcısını açığa çıkarabilirsiniz.
  2. Bir sınıf oluşturun, buna IDictionary uygulayan ExpirableItemsDictionary diyelim. Tüketici tarafından tanımlanan genel bir sınıf yapmayı tercih ediyorum.
  3. # 2'de oluşturulan sınıfta, özellik olarak Dictionary> ekleyin ve InnerDictionary olarak adlandırın.
  4. # 2'de oluşturulan sınıftaki if IDictionary uygulaması, önbelleğe alınmış öğeleri depolamak için InnerDictionary kullanmalıdır. Kapsülleme, yukarıda # 1'de oluşturulan türün örnekleri aracılığıyla önbelleğe alma yöntemi ayrıntılarını gizler.
  5. Dizin oluşturucunun (bu []), ContainsKey (), vb., Bir değeri döndürmeden önce süresi dolmuş öğeleri temizlemeye ve süresi dolmuş öğeleri kaldırmaya dikkat edin. Öğe kaldırılmışsa alıcılarda null döndür.
  6. Tüm alıcılar, ayarlayıcılar, ContainsKey () ve özellikle son kullanma tarihi geçmiş öğeleri temizlerken iş parçacığı kilitlerini kullanın.
  7. Son kullanma tarihi nedeniyle bir öğe kaldırıldığında bir etkinlik oluşturun.
  8. Bir System.Threading.Timer örneği ekleyin ve süresi dolan öğeleri her 15 saniyede bir otomatik olarak kaldırmak için başlatma sırasında donatın. Bu, ASP.NET önbelleğiyle aynı davranıştır.
  9. Zaten varsa, öğenin kapsayıcısındaki (Süresi dolan örnek) zaman damgasını değiştirerek kayan sona erme süresini dışarı iten bir AddOrUpdate () rutini eklemek isteyebilirsiniz.

Microsoft orijinal tasarımlarını desteklemek zorundadır çünkü kullanıcı tabanı bunlara bağımlıdır, ancak bu onların iyi tasarımlar oldukları anlamına gelmez.

Artıları:

  1. Uygulama üzerinde tam kontrole sahipsiniz .
  2. Can KURUTMA pekiştirmek varsayılan önbelleğe alma davranışları kurma ve sonra sadece önbelleğe alma bildirmek olmadan anahtar / değer çiftlerini bırakarak Öğe eklemek her zaman detayları.
  3. Yani modern arayüzler uygulayabilir IDictionary<K,T>. Bu, arayüzü bir sözlük arayüzü olarak daha öngörülebilir olduğu için tüketmeyi çok daha kolay hale getirir ve ayrıca, IDictionary <> ile çalışan yardımcılar ve genişletme yöntemleri için daha erişilebilir hale getirir.
  4. Önbelleğe alma ayrıntıları , örneğin InnerDictionary'nizi salt okunur bir özellik aracılığıyla açığa çıkararak, önbelleğe alma stratejinize göre açık birim testleri yazmanıza ve temel önbelleğe alma uygulamanızı, üzerine inşa edilen ek önbelleğe alma stratejileriyle genişletmenize olanak sağlayarak, kapsüllenmemiş olabilir .
  5. Kendilerini ASP.NET önbelleğinin .NET 1.0 tarzı sözdizimi veya Önbelleğe Alma Uygulama Bloğu ile zaten rahat hissedenler için tanıdık bir arabirim olmasa da, arabirimi istediğiniz gibi görünecek şekilde tanımlayabilirsiniz .
  6. Anahtarlar için herhangi bir türü kullanabilir. Jenerik ilaçların yaratılmasının bir nedeni budur. Her şey bir dizeyle anahtarlanmamalıdır.

Eksileri:

  1. Microsoft tarafından icat edilmediği ve desteklenmediği için aynı kalite güvencesine sahip olmayacak.
  2. Yalnızca yukarıda anlattığım talimatların uygulandığını varsayarsak, öncelik temelinde belleği temizlemek için öğeleri "ister istemez" temizlemiyor (bu, yine de bir önbelleğin köşe durum yardımcı program işlevidir .. Önbelleği kullanacağınız yerde RAM SATIN ALIN , RAM ucuzdur).

Bu dört seçenek arasında tercihim bu. Bu temel önbelleğe alma çözümünü uyguladım. Şimdiye kadar mükemmel çalışıyor gibi görünüyor, bilinen bir hata yok (lütfen aşağıdaki yorumlarla bana ulaşın veya varsa jon-at-jondavis'den iletişime geçin !!) ve bunu ihtiyaç duyan tüm küçük yan projelerimde kullanmayı düşünüyorum temel önbelleğe alma. İşte burada:

Github bağlantısı: https://github.com/kroimon/ExpirableItemDictionary

Eski Bağlantı: ExpirableItemDictionary.zip

Bahsetmeye Değer: AppFabric, NoSQL, Et Al

Bu blog makalesinin başlığının "Ağır Hizmet Önbelleğe Alma" yerine "Basit Önbelleğe Alma" anlamına geldiğine dikkat edin. Ağır hizmet işlerine girmek istiyorsanız, özel, ölçeklenebilir çözümlere bakmalısınız.



3

MemoryCache o, saklanan bir önbellektir diyor ki, hafızada

HttpRuntime.Cache (bkz. Http://msdn.microsoft.com/en-us/library/system.web.httpruntime.cache(v=vs.100).aspx ve http://msdn.microsoft.com/en- us / library / system.web.caching.cache.aspx ) uygulamanızda ne yapılandırırsanız yapılandırın devam eder.

bkz. örneğin "ASP.NET 4.0: Özel çıktı önbellek sağlayıcıları yazma" http://weblogs.asp.net/gunnarpeipman/archive/2009/11/19/asp-net-4-0-writing-custom-output-cache -providers.aspx


1
Hm, ikinci bağlantının yanıltıcı olmadığından emin değilim, çünkü OutputCache hakkında konuşuyor ve OutputCacheProvider uygulanıyor.
Giedrius

Hm, farklı bir konfigürasyon kullanarak System.Web.Caching.Cache'de kalabileceğinizi söyleyebileceğim yeri bulamıyorum
Giedrius

2

MemoryCache.Default, Core'da "System.Web.Caching" ve "HttpRuntime" olmadığı için klasik bir ASP.NET MVC uygulamasını ASP.NET Core'a geçiriyorsanız bir "köprü" görevi de görebilir.

Ayrıca bir boolöğeyi 20000 kez saklamak için küçük bir ölçüt yazdım (ve onu geri almak için başka bir ölçüt) ve MemoryCache iki kat daha yavaş görünüyor (27ms'ye karşı 13ms - bu 20k yinelemenin tümü için toplam) ama ikisi de süper hızlı ve bu muhtemelen göz ardı edilebilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.