Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Rick Anderson, John Luo ve Steve Smith tarafından
Önbelleğe alma, içerik oluşturmak için gereken çalışmayı azaltarak uygulamanın performansını ve ölçeklenebilirliğini önemli ölçüde artırabilir. Önbelleğe alma, seyrek değişen ve oluşturulması pahalı olan verilerle en iyi şekilde çalışır. Önbelleğe alma, kaynaktan çok daha hızlı döndürülebilen verilerin bir kopyasını oluşturur. Uygulamalar hiçbir zaman önbelleğe alınmış verilere bağımlı olmayacak şekilde yazılmalı ve test edilmelidir.
ASP.NET Core birkaç farklı önbelleği destekler. En basit önbellek IMemoryCache arayüzüne dayanmaktadır.
IMemoryCache , web sunucusunun belleğinde depolanan bir önbelleği temsil eder. Bir sunucu grubunda (birden çok sunucu) çalışan uygulamalar, bellek içi önbelleği kullanırken oturumların yapışkan olmasını sağlamalıdır. Yapışkan oturumlar, bir istemciden gelen isteklerin tümünün aynı sunucuya gitmesini sağlar. Örneğin, bir Azure web uygulaması tüm istekleri aynı sunucuya yönlendirmek için Microsoft Uygulama İsteği Yönlendirme (ARR) kullanır.
Bir web grubundaki yapışkan olmayan oturumlar, önbellek tutarlılığı sorunlarını önlemek için dağıtılmış bir önbellek gerektirir. Bazı uygulamalarda, dağıtılmış önbellek bellek içi önbellekten daha yüksek ölçeği genişletmeyi destekleyebilir. Dağıtılmış önbellek kullanmak, önbellek belleğini bir dış işleme boşaltır.
Bellek içi önbellek herhangi bir nesneyi depolayabilir. Dağıtılmış önbellek arabirimi byte[] ile sınırlıdır. Bellek içi ve dağıtılmış önbellek deposu önbellek öğelerini anahtar-değer çiftleri olarak depolar.
"System.Runtime.Caching/MemoryCache'i kullan"
System.Runtime.Caching / MemoryCache (NuGet paketi) ile kullanılabilir:
- .NET Standart 2.0 veya üzeri
- .NET Standard 2.0 veya sonrası için hedeflenen herhangi bir .NET uygulaması (ASP.NET Core 3.1 veya üzeri gibi)
- .NET Framework 4.5 veya üzeri
Microsoft. Extensions.Caching.Memory/IMemoryCache (bu makalede açıklanmıştır) System.Runtime.Caching/MemoryCache ASP.NET Core ile daha iyi tümleştirme sunduğundan önerilir. Örneğin, IMemoryCache ASP.NET Core bağımlılık enjeksiyonu ile doğal olarak çalışır.
kodu ASP.NET 4.x'ten ASP.NET Core'a aktarırken uyumluluk köprüsü olarak kullanın System.Runtime.Caching/MemoryCache .
Bellek içi önbelleğe alma yönergelerini gözden geçirin
Aşağıdaki yönergeler bellek içi önbelleğe alma için geçerlidir:
Kod her zaman verileri getirmek için bir geri dönüş seçeneğine sahip olmalı ve önbelleğe alınmış bir değerin kullanılabilirliğine bağlı olmamalıdır .
Önbellek yetersiz bir kaynak olan belleği kullanır. Önbellek büyümesini sınırla:
Önbelleğe dış giriş eklemeyin. Örneğin, kullanıcı tarafından sağlanan rastgele girişin önbellek anahtarı olarak kullanılması önerilmez çünkü giriş öngörülemeyen miktarda bellek tüketebilir.
Önbellek büyümesini sınırlamak için süre sonu kullanma.
Önbellek boyutunu sınırlamak için SetSize, Size ve SizeLimit kullanın. ASP.NET Core çalışma zamanı önbellek boyutunu bellek baskısına göre sınırlandırmaz. Önbellek boyutunu sınırlamak geliştiricinin sorumluluğundadır.
IMemoryCache örneği oluşturma
Bellek içi önbelleğe alma, bir uygulamanın bağımlılık enjeksiyonu kullanarak eriştiği bir hizmettir.
Warning
Aynı önbellek birden çok çerçeve veya kitaplık tarafından kullanılıyorsa, bu paylaşılan bir önbellektir.
Bağımlılık enjeksiyonu ile bir paylaşılan bellek önbelleği kullanıyorsanız ve önbellek boyutunu sınırlamak için SetSize, Size ve SizeLimit kullanıyorsanız, uygulama çökmeye veya hata vermeye müsait olabilir.
Önbellekte boyut sınırı ayarlandığında, tüm girdiler eklendiğinde bir boyut belirtmelidir. Geliştiriciler paylaşılan önbelleği kullananlar üzerinde tam denetime sahip olmadığından bu yaklaşım sorunlara yol açabilir.
Önbellek boyutunu SetSize yöntemiyle, Size özelliğiyle veya SizeLimit özelliğiyle sınırlamak için, önbelleğe alma amacıyla bir önbellek tekil örneği oluşturun. Daha fazla bilgi ve örnek için bkz. Önbellek boyutunu sınırlamak için SetSize, Size ve SizeLimit kullanma.
Oluşturucudaki IMemoryCache örneği isteyin:
public class IndexModel : PageModel
{
private readonly IMemoryCache _memoryCache;
public IndexModel(IMemoryCache memoryCache) =>
_memoryCache = memoryCache;
// ...
Aşağıdaki kod, önbellekte bir zamanın olup olmadığını denetlemek için TryGetValue metodunu kullanır. Zaman önbelleğe alınmadığında, yeni bir giriş oluşturulur ve Set yöntemiyle önbelleğe eklenir.
public void OnGet()
{
CurrentDateTime = DateTime.Now;
if (!_memoryCache.TryGetValue(CacheKeys.Entry, out DateTime cacheValue))
{
cacheValue = CurrentDateTime;
var cacheEntryOptions = new MemoryCacheEntryOptions()
.SetSlidingExpiration(TimeSpan.FromSeconds(3));
_memoryCache.Set(CacheKeys.Entry, cacheValue, cacheEntryOptions);
}
CacheCurrentDateTime = cacheValue;
}
Yukarıdaki kodda, önbellek girdisi 3 saniyelik kayan süre sonu ile yapılandırılır. Önbellek girdisine 3 saniyeden fazla erişilmezse, girdi önbellekten çıkarılır. Önbellek girdisine her erişildiğinde, önbellekte 3 saniye daha kalır.
CacheKeys sınıfı, indirme örneğinin bir parçasıdır.
Geçerli saat ve önbelleğe alınan süre görüntülenir:
<ul>
<li>Current Time: @Model.CurrentDateTime</li>
<li>Cached Time: @Model.CacheCurrentDateTime</li>
</ul>
Aşağıdaki kod, Set uzantı yöntemini kullanarak MemoryCacheEntryOptions olmadan, verileri göreli bir süre için önbelleğe alır:
_memoryCache.Set(CacheKeys.Entry, DateTime.Now, TimeSpan.FromDays(1));
Önceki kodda, önbellek girdisi bir günlük göreli süre sonuyla yapılandırılır. Zaman aşımı süresi boyunca girdiye erişilmiş olsa bile önbellek girdisi bir gün sonra önbellekten çıkarılır.
Aşağıdaki kod, verileri önbelleğe almak için GetOrCreate ve GetOrCreateAsync yöntemlerini kullanır.
public void OnGetCacheGetOrCreate()
{
var cachedValue = _memoryCache.GetOrCreate(
CacheKeys.Entry,
cacheEntry =>
{
cacheEntry.SlidingExpiration = TimeSpan.FromSeconds(3);
return DateTime.Now;
});
// ...
}
public async Task OnGetCacheGetOrCreateAsync()
{
var cachedValue = await _memoryCache.GetOrCreateAsync(
CacheKeys.Entry,
cacheEntry =>
{
cacheEntry.SlidingExpiration = TimeSpan.FromSeconds(3);
return Task.FromResult(DateTime.Now);
});
// ...
}
Aşağıdaki kod önbelleğe alınmış zamanı getirmek için yöntemini çağırır Get :
var cacheEntry = _memoryCache.Get<DateTime?>(CacheKeys.Entry);
Aşağıdaki kod, mutlak süre sonuyla önbelleğe alınmış bir öğe alır veya oluşturur:
var cachedValue = _memoryCache.GetOrCreate(
CacheKeys.Entry,
cacheEntry =>
{
cacheEntry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(20);
return DateTime.Now;
});
Yalnızca kayan süre sonu olan önbelleğe alınmış bir öğe kümesinin süresi hiç dolmama riski altındadır. Önbelleğe alınan öğeye kayan süre sonu aralığı içinde tekrar tekrar erişilirse, öğenin süresi hiçbir zaman dolmaz. Kayan süre sonunu mutlak süre sonuyla birleştirmek, öğenin süresinin dolmasına garanti eder. Mutlak süre sonu, öğenin ne kadar süreyle önbelleğe alınabileceğine ilişkin bir üst sınır ayarlar. Kayan süre sonu aralığı içinde öğe istenmezse, yine de öğenin süresinin daha erken dolmasına izin verir. Kayan süre sonu aralığı veya mutlak süre sonu süresi geçerse, öğe önbellekten çıkarılır.
Aşağıdaki kod, hem kayan hem de mutlak süre sonu olan önbelleğe alınmış bir öğeyi alır ve oluşturur.
var cachedValue = _memoryCache.GetOrCreate(
CacheKeys.CallbackEntry,
cacheEntry =>
{
cacheEntry.SlidingExpiration = TimeSpan.FromSeconds(3);
cacheEntry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(20);
return DateTime.Now;
});
Yukarıdaki kod, verilerin mutlak süreden daha uzun süre önbelleğe alınmadığından emin olur.
GetOrCreate, GetOrCreateAsyncve Get sınıfındaki CacheExtensions uzantı yöntemleridir. Bu yöntemler, IMemoryCache'ün yeteneğini genişletir.
Bir giriş için MemoryCacheEntryOptions oluşturun
Aşağıdaki örnek, bir giriş için MemoryCacheEntryOptions nasıl oluşturulacağını göstermektedir. Kod aşağıdaki görevleri tamamlar:
Önbellek önceliğini CacheItemPriority.NeverRemove olarak ayarlar.
Öğe önbellekten silindikten sonra çağrılacak bir PostEvictionDelegate ayarlar. Geri çağırma, öğeyi önbellekten kaldıran koddan farklı bir iş parçacığı üzerinde çalışır.
public void OnGetCacheRegisterPostEvictionCallback()
{
var memoryCacheEntryOptions = new MemoryCacheEntryOptions()
.SetPriority(CacheItemPriority.NeverRemove)
.RegisterPostEvictionCallback(PostEvictionCallback, _memoryCache);
_memoryCache.Set(CacheKeys.CallbackEntry, DateTime.Now, memoryCacheEntryOptions);
}
private static void PostEvictionCallback(
object cacheKey, object cacheValue, EvictionReason evictionReason, object state)
{
var memoryCache = (IMemoryCache)state;
memoryCache.Set(
CacheKeys.CallbackMessage,
$"Entry {cacheKey} was evicted: {evictionReason}.");
}
SetSize, Size ve SizeLimit ile önbellek boyutunu sınırlama
Bir MemoryCache örnek isteğe bağlı olarak bir boyut sınırı belirtebilir ve zorunlu kılabilir. Önbellekte girdilerin boyutunu ölçen bir mekanizma olmadığından önbellek boyutu sınırı tanımlı bir ölçü birimine sahip değildir. Önbellek boyutu sınırı ayarlanırsa, tüm girdilerin boyutu belirtmesi gerekir. ASP.NET Core çalışma zamanı, bellek baskısına bağlı olarak önbellek boyutunu sınırlamaz. Önbellek boyutunu sınırlamak geliştiriciye bağlı. Belirtilen boyut, geliştiricinin seçtiği birim cinsindendir.
Örneğin:
- Web uygulaması öncelikli olarak dizeleri önbelleğe alırsa, her önbellek girdisi boyutu dize uzunluğu olabilir.
- Uygulama tüm girişlerin boyutunu 1 olarak belirtebilir ve boyut sınırı girdi sayısıdır.
SizeLimit Özellik ayarlanmadıysa, önbellek bağlı olmadan büyür. ASP.NET Core çalışma zamanı, sistem belleği düşük olduğunda önbelleği kırpmaz. Uygulamaların mimarisinin şu şekilde tasarlanması gerekir:
- Önbellek büyümesini sınırlayın.
- Compact Kullanılabilir bellek sınırlı olduğunda veya Remove yöntemini çağırın.
Aşağıdaki kodMemoryCache yoluyla erişilebilen bir birimsiz sabit boyutlu örnek oluşturur:
public class MyMemoryCache
{
public MemoryCache Cache { get; } = new MemoryCache(
new MemoryCacheOptions
{
SizeLimit = 1024
});
}
SizeLimit özelliğinin birimleri yok. Önbelleğe alınan girdilerin, önbellek boyutu sınırı ayarlandığında en uygun olarak değerlendirdikleri birimlerde boyutu belirtmesi gerekir. Önbellek örneğinin tüm kullanıcıları aynı birim sistemini kullanmalıdır. Önbelleğe alınan girdi boyutlarının toplamı tarafından SizeLimitbelirtilen değeri aşarsa bir girdi önbelleğe alınmaz. Önbellek boyutu sınırı ayarlı değilse, girdide ayarlanan önbellek boyutu yoksayılır.
Aşağıdaki kod, MyMemoryCache örneğini bağımlı enjeksiyonu kapsayıcısıyla kaydeder:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddSingleton<MyMemoryCache>();
MyMemoryCache , bu boyut sınırlı önbelleğin farkında olan ve önbellek giriş boyutunu uygun şekilde ayarlamayı bilen bileşenler için bağımsız bir bellek önbelleği olarak oluşturulur.
Önbellek girdisinin boyutu, uzantı yöntemi veya SetSize özelliği kullanılarak Size ayarlanabilir:
if (!_myMemoryCache.Cache.TryGetValue(CacheKeys.Entry, out DateTime cacheValue))
{
var cacheEntryOptions = new MemoryCacheEntryOptions()
.SetSize(1);
// cacheEntryOptions.Size = 1;
_myMemoryCache.Cache.Set(CacheKeys.Entry, cacheValue, cacheEntryOptions);
}
Yukarıdaki kodda vurgulanan iki satır, önbellek girdisinin boyutunun ayarlanmasıyla aynı sonucu elde ediyor.
SetSize yöntemi, çağrılar new MemoryCacheOptions() üzerine zincirlenirken kolaylık sağlamak için sağlanır.
MemoryCache.Compact ile önbellek öğelerini kaldırma
yöntemi, MemoryCache.Compact önbelleğin belirtilen yüzdesini aşağıdaki sırayla kaldırmaya çalışır:
- Süresi dolan tüm öğeler
- Önce en düşük öncelikli öğelerin kaldırıldığı önceliğe göre öğeler
- En son kullanılan nesneler
- En erken mutlak süre sonu olan öğeler
- En erken kayan süre sonu olan öğeler
Önceliğe NeverRemove sahip sabitlenmiş öğeler hiçbir zaman kaldırılmaz. Aşağıdaki kod, bir önbellek öğesini kaldırır ve önbelleğe alınmış girdilerin yüzde 25'ini kaldırmak için Compact yöntemini çağırır.
_myMemoryCache.Cache.Remove(CacheKeys.Entry);
_myMemoryCache.Cache.Compact(.25);
Daha fazla bilgi için GitHub'daki Compact kaynağına bakın.
Süresi dolan bağımlılıkları olan önbellek girdisini çıkartma
Aşağıdaki örnek, bağımlı bir girişin süresi dolduğunda önbellek girişinin nasıl sona erdirileceğini gösterir. Önbelleğe alınan öğeye bir CancellationChangeToken eklenir.
Cancel yöntemi CancellationTokenSource nesnesi üzerinde çağrıldığında, her iki önbellek girdisi de çıkarılır.
public void OnGetCacheCreateDependent()
{
var cancellationTokenSource = new CancellationTokenSource();
_memoryCache.Set(
CacheKeys.DependentCancellationTokenSource,
cancellationTokenSource);
using var parentCacheEntry = _memoryCache.CreateEntry(CacheKeys.Parent);
parentCacheEntry.Value = DateTime.Now;
_memoryCache.Set(
CacheKeys.Child,
DateTime.Now,
new CancellationChangeToken(cancellationTokenSource.Token));
}
public void OnGetCacheRemoveDependent()
{
var cancellationTokenSource = _memoryCache.Get<CancellationTokenSource>(
CacheKeys.DependentCancellationTokenSource);
cancellationTokenSource.Cancel();
}
Bir CancellationTokenSource nesne kullandığınızda, birden çok önbellek girdisini grup olarak çıkarabilirsiniz.
using Yukarıdaki koddaki desenle, kapsamın using içinde oluşturulan önbellek girdileri tetikleyicileri ve süre sonu ayarlarını devralır.
Bellek içi önbelleğe alma hakkındaki notları gözden geçirme
Aşağıdaki notlar bellek içi önbelleğe alma için geçerlidir:
Süresinin dolması arka planda gerçekleşmez.
Süresi dolan öğeler için önbelleği etkin bir şekilde tarayan zamanlayıcı yoktur. Önbellekteki herhangi bir etkinlik (,
Get,TryGetValueveyaSetaracılığıylaRemove) süresi dolan öğeler için arka plan taraması tetikleyebilir. Nesne üzerindeCancellationTokenSourceayarlanmış bir zamanlayıcı (CancelAfter yöntemini kullanarak) girişi kaldırır ve süresi dolan öğeler için taramayı tetikler.Aşağıdaki örnek, kayıtlı belirteç için CancellationTokenSource(TimeSpan) aşırı yüklenmiş oluşturucuyu kullanır. Bu jeton tetiklendiğinde, kaydı hemen kaldırır ve geriye çağırma işlevlerini çalıştırır.
if (!_memoryCache.TryGetValue(CacheKeys.Entry, out DateTime cacheValue)) { cacheValue = DateTime.Now; var cancellationTokenSource = new CancellationTokenSource( TimeSpan.FromSeconds(10)); var cacheEntryOptions = new MemoryCacheEntryOptions() .AddExpirationToken( new CancellationChangeToken(cancellationTokenSource.Token)) .RegisterPostEvictionCallback((key, value, reason, state) => { ((CancellationTokenSource)state).Dispose(); }, cancellationTokenSource); _memoryCache.Set(CacheKeys.Entry, cacheValue, cacheEntryOptions); }Bir önbellek öğesini yeniden doldurmaya yönelik bir geri çağırma kullandığınızda:
- Geri çağırma tamamlanmadığından birden çok istek önbelleğe alınmış anahtar değerinin boş olduğunu bulabilir.
- Bu yaklaşım, önbelleğe alınmış öğenin birkaç iş parçacığı tarafından güncellenmesiyle sonuçlanabilir.
Bir önbellek girdisi (üst) başka bir giriş (alt) oluşturduğunda, alt öğe üst girişin süre sonu belirteçlerini ve zamana bağlı süre sonu ayarlarını kopyalar. Üst girdi el ile kaldırıldığında veya güncelleştirildiğinde alt öğe süresi dolmaz.
Önbellek öğesi PostEvictionCallbacks önbellekten çıkarıldıktan sonra hangi geri çağırmaların tetikleneceğini belirtmek için bu özelliği kullanın.
Çoğu uygulamada
IMemoryCacheetkindir. Örneğin,AddMvc,AddControllersWithViews,AddRazorPages,AddMvcCore().AddRazorViewEngineve birçok başkaAdd{Service}yöntemini Program.cs dosyasında çağırmakIMemoryCacheetkinleştirir.Belirtilen
Add{Service}yöntemlerinden birini çağırmayan uygulamalar için, Program.cs dosyasında AddMemoryCache yöntemini çağırmanız gerekebilir.
Arka plan önbellek güncelleştirmesi kullanma
Önbelleği güncelleştirmek için arabirimi gibi bir IHostedService kullanın. Arka plan hizmeti, girdileri yeniden derleyebilir ve yalnızca hazır olduktan sonra önbelleğe atayabilir.
İlgili içerik
Örnek kodu görüntüleme veya indirme (indirme)
Önbelleğe almayla ilgili temel bilgiler
Önbelleğe alma, içerik oluşturmak için gereken çalışmayı azaltarak uygulamanın performansını ve ölçeklenebilirliğini önemli ölçüde artırabilir. Önbelleğe alma, seyrek değişen ve oluşturulması pahalı olan verilerle en iyi şekilde çalışır. Önbelleğe alma, kaynaktan çok daha hızlı döndürülebilen verilerin bir kopyasını oluşturur. Uygulamalar hiçbir zaman önbelleğe alınmış verilere bağımlı olmayacak şekilde yazılmalı ve test edilmelidir.
ASP.NET Core birkaç farklı önbelleği destekler. En basit önbellek IMemoryCache üzerine kuruludur.
IMemoryCache , web sunucusunun belleğinde depolanan bir önbelleği temsil eder. Bir sunucu grubunda (birden çok sunucu) çalışan uygulamalar, bellek içi önbelleği kullanırken oturumların yapışkan olmasını sağlamalıdır. Yapışkan oturumlar, bir istemciden gelen sonraki isteklerin tümünün aynı sunucuya gitmesini sağlar. Örneğin, Azure Web uygulamaları sonraki tüm istekleri aynı sunucuya yönlendirmek için Uygulama İsteği Yönlendirmesi'ni (ARR) kullanır.
Web grubundaki yapışkan olmayan oturumlar, önbellek tutarlılığı sorunlarını önlemek için dağıtılmış bir önbellek gerektirir. Bazı uygulamalarda, dağıtılmış önbellek bellek içi önbellekten daha yüksek ölçeği genişletmeyi destekleyebilir. Dağıtılmış önbellek kullanmak, önbellek belleğini bir dış işleme boşaltır.
Bellek içi önbellek herhangi bir nesneyi depolayabilir. Dağıtılmış önbellek arabirimi byte[] ile sınırlıdır. Bellek içi ve dağıtılmış önbellek deposu önbellek öğelerini anahtar-değer çiftleri olarak depolar.
System.Runtime.Caching/MemoryCache
System.Runtime.Caching / MemoryCache (NuGet paketi) ile kullanılabilir:
- .NET Standard 2.0 veya üzeri.
- .NET Standard 2.0 veya üstünü hedefleyen herhangi bir .NET uygulaması. Örneğin, ASP.NET Core 3.1 veya daha yeni bir sürümü.
- .NET Framework 4.5 veya üzeri.
Microsoft.Extensions.Caching.Memory/IMemoryCache (bu makalede açıklanmıştır), ASP.NET Core ile daha iyi tümleştirildiğinden System.Runtime.Caching/MemoryCache önerilir. Örneğin, IMemoryCache ASP.NET Core bağımlılık enjeksiyonu ile doğal olarak çalışır.
kodu ASP.NET 4.x'ten ASP.NET Core'a aktarırken uyumluluk köprüsü olarak kullanın System.Runtime.Caching/MemoryCache .
Önbellek yönergeleri
- Kod her zaman verileri getirmek için bir geri dönüş seçeneğine sahip olmalı ve önbelleğe alınmış bir değerin kullanılabilir olmasına bağlı olmamalıdır .
- Önbellekte az miktarda kaynak ve bellek kullanılır. Önbellek büyümesini sınırla:
- Dış girişleri önbellek anahtarı olarak kullanmayın.
- Önbellek büyümesini sınırlamak için süre sonu kullanma.
- Önbellek boyutunu sınırlamak için SetSize, Size ve SizeLimit kullanın. ASP.NET Core çalışma zamanı, bellek baskısına göre önbellek boyutunu sınırlamaz . Önbellek boyutunu sınırlamak geliştiriciye bağlı.
IMemoryCache kullanma
Warning
Paylaşılan bir bellek önbelleğini Bağımlılık Enjeksiyonu ile kullanmak ve önbellek boyutunu sınırlamak için SetSize, Size veya SizeLimit çağrısı yapmak uygulamanın başarısız olmasına neden olabilir. Önbellekte boyut sınırı ayarlandığında, tüm girdiler eklenirken bir boyut belirtmelidir. Geliştiriciler paylaşılan önbelleği kullananlar üzerinde tam denetime sahip olmadığından bu sorunlara yol açabilir.
Önbelleği sınırlamak için SetSize, Size veya SizeLimit kullanırken, önbelleğe alma için bir önbellek singletonu oluşturun. Daha fazla bilgi ve örnek için bkz. Önbellek boyutunu sınırlamak için SetSize, Size ve SizeLimit kullanma.
Paylaşılan önbellek, diğer çerçeveler veya kitaplıklar tarafından paylaşılan önbellektir.
Bellek içi önbelleğe alma, Bağımlılık Enjeksiyonu kullanılarak bir uygulamadan referans verilen bir hizmettir. Oluşturucudaki IMemoryCache örneği isteyin:
public class HomeController : Controller
{
private IMemoryCache _cache;
public HomeController(IMemoryCache memoryCache)
{
_cache = memoryCache;
}
Aşağıdaki kod, bir saatin önbellekte olup olmadığını denetlemek için kullanır TryGetValue . Bir zaman önbelleğe alınmazsa, yeni bir giriş oluşturulur ve Set ile önbelleğe eklenir.
CacheKeys sınıfı, indirme örneğinin bir parçasıdır.
public static class CacheKeys
{
public static string Entry => "_Entry";
public static string CallbackEntry => "_Callback";
public static string CallbackMessage => "_CallbackMessage";
public static string Parent => "_Parent";
public static string Child => "_Child";
public static string DependentMessage => "_DependentMessage";
public static string DependentCTS => "_DependentCTS";
public static string Ticks => "_Ticks";
public static string CancelMsg => "_CancelMsg";
public static string CancelTokenSource => "_CancelTokenSource";
}
public IActionResult CacheTryGetValueSet()
{
DateTime cacheEntry;
// Look for cache key.
if (!_cache.TryGetValue(CacheKeys.Entry, out cacheEntry))
{
// Key not in cache, so get data.
cacheEntry = DateTime.Now;
// Set cache options.
var cacheEntryOptions = new MemoryCacheEntryOptions()
// Keep in cache for this time, reset time if accessed.
.SetSlidingExpiration(TimeSpan.FromSeconds(3));
// Save data in cache.
_cache.Set(CacheKeys.Entry, cacheEntry, cacheEntryOptions);
}
return View("Cache", cacheEntry);
}
Geçerli saat ve önbelleğe alınan süre görüntülenir:
@model DateTime?
<div>
<h2>Actions</h2>
<ul>
<li><a asp-controller="Home" asp-action="CacheTryGetValueSet">TryGetValue and Set</a></li>
<li><a asp-controller="Home" asp-action="CacheGet">Get</a></li>
<li><a asp-controller="Home" asp-action="CacheGetOrCreate">GetOrCreate</a></li>
<li><a asp-controller="Home" asp-action="CacheGetOrCreateAsynchronous">CacheGetOrCreateAsynchronous</a></li>
<li><a asp-controller="Home" asp-action="CacheRemove">Remove</a></li>
<li><a asp-controller="Home" asp-action="CacheGetOrCreateAbs">CacheGetOrCreateAbs</a></li>
<li><a asp-controller="Home" asp-action="CacheGetOrCreateAbsSliding">CacheGetOrCreateAbsSliding</a></li>
</ul>
</div>
<h3>Current Time: @DateTime.Now.TimeOfDay.ToString()</h3>
<h3>Cached Time: @(Model == null ? "No cached entry found" : Model.Value.TimeOfDay.ToString())</h3>
Aşağıdaki kod, Set uzantı yöntemini kullanarak, MemoryCacheEntryOptions nesnesini oluşturmadan, verileri göreli bir süre için önbelleğe alır:
public IActionResult SetCacheRelativeExpiration()
{
DateTime cacheEntry;
// Look for cache key.
if (!_cache.TryGetValue(CacheKeys.Entry, out cacheEntry))
{
// Key not in cache, so get data.
cacheEntry = DateTime.Now;
// Save data in cache and set the relative expiration time to one day
_cache.Set(CacheKeys.Entry, cacheEntry, TimeSpan.FromDays(1));
}
return View("Cache", cacheEntry);
}
Zaman aşımı süresi içinde istekler olduğunda önbelleğe alınan DateTime değer önbellekte kalır.
Aşağıdaki kod, verileri önbelleğe almak için GetOrCreate ve GetOrCreateAsync kullanır.
public IActionResult CacheGetOrCreate()
{
var cacheEntry = _cache.GetOrCreate(CacheKeys.Entry, entry =>
{
entry.SlidingExpiration = TimeSpan.FromSeconds(3);
return DateTime.Now;
});
return View("Cache", cacheEntry);
}
public async Task<IActionResult> CacheGetOrCreateAsynchronous()
{
var cacheEntry = await
_cache.GetOrCreateAsync(CacheKeys.Entry, entry =>
{
entry.SlidingExpiration = TimeSpan.FromSeconds(3);
return Task.FromResult(DateTime.Now);
});
return View("Cache", cacheEntry);
}
Önbelleğe alınmış zamanı getirmek için aşağıdaki kod Get'yi çağırır:
public IActionResult CacheGet()
{
var cacheEntry = _cache.Get<DateTime?>(CacheKeys.Entry);
return View("Cache", cacheEntry);
}
Aşağıdaki kod, mutlak süre sonuyla önbelleğe alınmış bir öğe alır veya oluşturur:
public IActionResult CacheGetOrCreateAbs()
{
var cacheEntry = _cache.GetOrCreate(CacheKeys.Entry, entry =>
{
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(10);
return DateTime.Now;
});
return View("Cache", cacheEntry);
}
Yalnızca kayan süre sonu olan önbelleğe alınmış bir öğe kümesinin süresi hiç dolmama riski altındadır. Önbelleğe alınan öğeye kayan süre sonu aralığı içinde tekrar tekrar erişilirse, öğenin süresi hiçbir zaman dolmaz. Öğenin süresinin dolduğundan emin olmak için kayan süre sonunu mutlak süre sonuyla birleştirin. Mutlak süre sonu, öğenin ne kadar süre önbelleğe alınabileceğine ilişkin bir üst sınır ayarlar ve kayan süre sonu aralığı içinde istenmezse öğenin süresinin daha erken dolmasına izin verir. Kayan süre sonu aralığı veya mutlak süre sonu süresi geçerse, öğe önbellekten çıkarılır.
Aşağıdaki kod, hem kayan hem de mutlak süre sonu olan önbelleğe alınmış bir öğeyi alır ve oluşturur.
public IActionResult CacheGetOrCreateAbsSliding()
{
var cacheEntry = _cache.GetOrCreate(CacheKeys.Entry, entry =>
{
entry.SetSlidingExpiration(TimeSpan.FromSeconds(3));
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(20);
return DateTime.Now;
});
return View("Cache", cacheEntry);
}
Yukarıdaki kod, verilerin mutlak süreden daha uzun süre önbelleğe alınmayacağını garanti eder.
GetOrCreate, GetOrCreateAsyncve Get sınıfındaki CacheExtensions uzantı yöntemleridir. Bu yöntemler, IMemoryCache'ün yeteneğini genişletir.
MemoryCacheEntryOptions
Aşağıdaki örnek:
- Kayan son kullanma süresini ayarlar. Önbelleğe alınan bu öğeye erişen istekler kayan süre sonu saatini sıfırlar.
- Önbellek önceliğini CacheItemPriority.NeverRemove olarak ayarlar.
- Girdi önbellekten çıkarıldıktan sonra çağrılacak bir PostEvictionDelegate ayarlar. Geri çağırma, öğeyi önbellekten kaldıran koddan farklı bir iş parçacığında çalıştırılır.
public IActionResult CreateCallbackEntry()
{
var cacheEntryOptions = new MemoryCacheEntryOptions()
// Pin to cache.
.SetPriority(CacheItemPriority.NeverRemove)
// Add eviction callback
.RegisterPostEvictionCallback(callback: EvictionCallback, state: this);
_cache.Set(CacheKeys.CallbackEntry, DateTime.Now, cacheEntryOptions);
return RedirectToAction("GetCallbackEntry");
}
public IActionResult GetCallbackEntry()
{
return View("Callback", new CallbackViewModel
{
CachedTime = _cache.Get<DateTime?>(CacheKeys.CallbackEntry),
Message = _cache.Get<string>(CacheKeys.CallbackMessage)
});
}
public IActionResult RemoveCallbackEntry()
{
_cache.Remove(CacheKeys.CallbackEntry);
return RedirectToAction("GetCallbackEntry");
}
private static void EvictionCallback(object key, object value,
EvictionReason reason, object state)
{
var message = $"Entry was evicted. Reason: {reason}.";
((HomeController)state)._cache.Set(CacheKeys.CallbackMessage, message);
}
Önbellek boyutunu sınırlamak için SetSize, Size ve SizeLimit kullanma
Bir MemoryCache örnek isteğe bağlı olarak bir boyut sınırı belirtebilir ve zorunlu kılabilir. Önbellekte girdilerin boyutunu ölçecek bir mekanizma olmadığından önbellek boyutu sınırı tanımlı bir ölçü birimine sahip değildir. Önbellek boyutu sınırı ayarlanırsa, tüm girdilerin boyutu belirtmesi gerekir. ASP.NET Core çalışma zamanı, önbellek boyutunu bellek baskısına göre sınırlamaz. Önbellek boyutunu sınırlamak geliştiriciye bağlı. Belirtilen boyut, geliştiricinin seçtiği birim cinsindendir.
Örneğin:
- Web uygulaması birincil olarak dizeleri önbelleğe almaksa, her önbellek girdisi boyutu dize uzunluğu olabilir.
- Uygulama tüm girişlerin boyutunu 1 olarak belirtebilir ve boyut sınırı girdi sayısıdır.
SizeLimit ayarlanmadıysa, önbellek sınırsız büyür. ASP.NET Core çalışma zamanı, sistem belleği düşük olduğunda önbelleği kırpmaz. Uygulamaların mimarisinin şu şekilde tasarlanması gerekir:
Aşağıdaki kodMemoryCache ile erişilebilen bir birimsiz sabit boyut oluşturur:
// using Microsoft.Extensions.Caching.Memory;
public class MyMemoryCache
{
public MemoryCache Cache { get; private set; }
public MyMemoryCache()
{
Cache = new MemoryCache(new MemoryCacheOptions
{
SizeLimit = 1024
});
}
}
SizeLimit birimleri yoktur. Önbellek boyutu sınırı ayarlandıysa, önbelleğe alınan girdilerin boyutu en uygun gördükleri birimlerde belirtmesi gerekir. Önbellek örneğinin tüm kullanıcıları aynı birim sistemini kullanmalıdır. Önbelleğe alınan girdi boyutlarının toplamı tarafından SizeLimitbelirtilen değeri aşarsa bir girdi önbelleğe alınmaz. Önbellek boyutu sınırı ayarlı değilse, girdide ayarlanan önbellek boyutu yoksayılır.
Aşağıdaki kod, MyMemoryCache ile bağımlılık enjeksiyonu kapsayıcısına kaydolur.
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddSingleton<MyMemoryCache>();
}
MyMemoryCache , bu boyut sınırlı önbelleğin farkında olan ve önbellek giriş boyutunu uygun şekilde ayarlamayı bilen bileşenler için bağımsız bir bellek önbelleği olarak oluşturulur.
Aşağıdaki kodda kullanılır MyMemoryCache:
public class SetSize : PageModel
{
private MemoryCache _cache;
public static readonly string MyKey = "_MyKey";
public SetSize(MyMemoryCache memoryCache)
{
_cache = memoryCache.Cache;
}
[TempData]
public string DateTime_Now { get; set; }
public IActionResult OnGet()
{
if (!_cache.TryGetValue(MyKey, out string cacheEntry))
{
// Key not in cache, so get data.
cacheEntry = DateTime.Now.TimeOfDay.ToString();
var cacheEntryOptions = new MemoryCacheEntryOptions()
// Set cache entry size by extension method.
.SetSize(1)
// Keep in cache for this time, reset time if accessed.
.SetSlidingExpiration(TimeSpan.FromSeconds(3));
// Set cache entry size via property.
// cacheEntryOptions.Size = 1;
// Save data in cache.
_cache.Set(MyKey, cacheEntry, cacheEntryOptions);
}
DateTime_Now = cacheEntry;
return RedirectToPage("./Index");
}
}
Önbellek girdisinin boyutu, Size veya SetSize uzantı yöntemleri ile ayarlanabilir.
public IActionResult OnGet()
{
if (!_cache.TryGetValue(MyKey, out string cacheEntry))
{
// Key not in cache, so get data.
cacheEntry = DateTime.Now.TimeOfDay.ToString();
var cacheEntryOptions = new MemoryCacheEntryOptions()
// Set cache entry size by extension method.
.SetSize(1)
// Keep in cache for this time, reset time if accessed.
.SetSlidingExpiration(TimeSpan.FromSeconds(3));
// Set cache entry size via property.
// cacheEntryOptions.Size = 1;
// Save data in cache.
_cache.Set(MyKey, cacheEntry, cacheEntryOptions);
}
DateTime_Now = cacheEntry;
return RedirectToPage("./Index");
}
MemoryCache.Compact
MemoryCache.Compact önbelleğin belirtilen yüzdesini aşağıdaki sırayla kaldırmaya çalışır:
- Süresi dolan tüm öğeler.
- Önceliğe göre öğeler. En düşük öncelikli öğeler önce kaldırılır.
- En az yakın zamanda kullanılan nesneler.
- En erken mutlak süre sonu olan öğeler.
- En erken kayan süre sonu olan öğeler.
Önceliğe NeverRemove sahip sabitlenmiş öğeler hiçbir zaman kaldırılmaz. Aşağıdaki kod bir önbellek öğesini kaldırır ve Compact'i çağırır.
_cache.Remove(MyKey);
// Remove 33% of cached items.
_cache.Compact(.33);
cache_size = _cache.Count;
Daha fazla bilgi için GitHub'daki Compact kaynağına bakın.
Önbellek bağımlılıkları
Aşağıdaki örnek, bağımlı bir girişin süresi dolduğunda önbellek girişinin nasıl sona erdirileceğini gösterir. Önbelleğe alınan öğeye bir CancellationChangeToken eklenir.
Cancel üzerinde CancellationTokenSource çağrıldığında, her iki önbellek girdisi de çıkarılır.
public IActionResult CreateDependentEntries()
{
var cts = new CancellationTokenSource();
_cache.Set(CacheKeys.DependentCTS, cts);
using (var entry = _cache.CreateEntry(CacheKeys.Parent))
{
// expire this entry if the dependant entry expires.
entry.Value = DateTime.Now;
entry.RegisterPostEvictionCallback(DependentEvictionCallback, this);
_cache.Set(CacheKeys.Child,
DateTime.Now,
new CancellationChangeToken(cts.Token));
}
return RedirectToAction("GetDependentEntries");
}
public IActionResult GetDependentEntries()
{
return View("Dependent", new DependentViewModel
{
ParentCachedTime = _cache.Get<DateTime?>(CacheKeys.Parent),
ChildCachedTime = _cache.Get<DateTime?>(CacheKeys.Child),
Message = _cache.Get<string>(CacheKeys.DependentMessage)
});
}
public IActionResult RemoveChildEntry()
{
_cache.Get<CancellationTokenSource>(CacheKeys.DependentCTS).Cancel();
return RedirectToAction("GetDependentEntries");
}
private static void DependentEvictionCallback(object key, object value,
EvictionReason reason, object state)
{
var message = $"Parent entry was evicted. Reason: {reason}.";
((HomeController)state)._cache.Set(CacheKeys.DependentMessage, message);
}
Bir CancellationTokenSource kullanarak birden çok önbellek girdisi grup olarak kaldırılabilir.
using Yukarıdaki koddaki desenle, bloğun using içinde oluşturulan önbellek girdileri tetikleyicileri ve süre sonu ayarlarını devralır.
Ek notlar
Süresinin dolması arka planda gerçekleşmez. Süresi dolan öğeler için önbelleği etkin bir şekilde tarar zamanlayıcı yoktur. Önbellekteki herhangi bir etkinlik (
Get,Set,Remove) süresi dolan öğeler için arka plan taraması tetikleyebilir.CancellationTokenSource(CancelAfter) üzerindeki bir zamanlayıcı, aynı zamanda girdiyi kaldırır ve süresi dolan öğeler için bir tarama tetikler. Aşağıdaki örnekte kayıtlı belirteç için kullanılır CancellationTokenSource(TimeSpan) . Bu belirteç tetiklendiğinde girişi hemen kaldırır ve çıkarma geri çağırmalarını başlatır:public IActionResult CacheAutoExpiringTryGetValueSet() { DateTime cacheEntry; if (!_cache.TryGetValue(CacheKeys.Entry, out cacheEntry)) { cacheEntry = DateTime.Now; var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); var cacheEntryOptions = new MemoryCacheEntryOptions() .AddExpirationToken(new CancellationChangeToken(cts.Token)); _cache.Set(CacheKeys.Entry, cacheEntry, cacheEntryOptions); } return View("Cache", cacheEntry); }Önbellek öğesini yeniden doldurmaya yönelik bir geri çağırma kullanılırken:
- Geri çağırma tamamlanmadığından birden çok istek önbelleğe alınmış anahtar değerini boş bulabilir.
- Bu, önbelleğe alınmış öğeyi birkaç iş parçacığının yeniden doldurmasıyla sonuçlanabilir.
Bir önbellek girdisi başka bir önbellek girişi oluşturmak için kullanıldığında, alt öğe üst girdinin süre sonu belirteçlerini ve zamana bağlı süre sonu ayarlarını kopyalar. Ebeveyn girişinin el ile kaldırılması veya güncellenmesiyle çocuğun süresi dolmaz.
Önbellek girdisi önbellekten çıkarıldıktan sonra tetiklenecek geri çağırmaları ayarlamak için kullanın PostEvictionCallbacks . Örnek kodda, CancellationTokenSource.Dispose(),
CancellationTokenSourcetarafından kullanılan yönetilmeyen kaynakları serbest bırakmak için çağrılır. Ancak,CancellationTokenSourcehâlâ önbellek girdisi tarafından kullanıldığı için hemen atılmaz.CancellationToken, belirli bir süre sonra süresi dolan bir önbellek girdisi oluşturmak içinMemoryCacheEntryOptionsöğesine iletilir. Bu nedenleDispose, önbellek girdisi kaldırılana veya süresi dolana kadar çağrılmamalıdır. Örnek kod, önbellek girdisi çıkarıldığında çağrılacak bir geri çağırmayı kaydetmek için RegisterPostEvictionCallback yöntemini çağırır ve bu geri çağırmadaCancellationTokenSource'yi serbest bırakır.Çoğu uygulamada
IMemoryCacheetkindir. Örneğin,AddMvc,AddControllersWithViews,AddRazorPages,AddMvcCore().AddRazorViewEngineve birçok başkaAdd{Service}yöntemininConfigureServicesiçinde çağrılmasıIMemoryCacheöğesini etkinleştirir. ÖncekiAdd{Service}yöntemlerinden birini çağırmayan uygulamalar için, AddMemoryCache içindeConfigureServicesçağrısı yapılması gerekebilir.
Arka plan önbelleği güncelleştirmesi
Önbelleği güncelleştirmek için gibi bir IHostedService kullanın. Arka plan hizmeti girdileri yeniden derleyebilir ve sonra bunları yalnızca hazır olduklarında önbelleğe atayabilir.
Ek kaynaklar
ASP.NET Core