ASP.NET Core 'de önbellek belleğiCache in-memory in ASP.NET Core

By Rick Anderson, John Luove Steve SmithBy Rick Anderson, John Luo, and Steve Smith

Örnek kodu görüntüleme veya indirme (nasıl indirileceği)View or download sample code (how to download)

Önbelleğe alma temelleriCaching basics

Önbelleğe alma, içerik oluşturmak için gereken işi azaltarak bir uygulamanın performansını ve ölçeklenebilirliğini önemli ölçüde iyileştirebilir.Caching can significantly improve the performance and scalability of an app by reducing the work required to generate content. Önbelleğe alma işlemi, seyrek olarak değişen ve üretime masraflı verilerle en iyi şekilde çalışıyor.Caching works best with data that changes infrequently and is expensive to generate. Önbelleğe alma, kaynaktan çok daha hızlı döndürülebilecek verilerin bir kopyasını oluşturur.Caching makes a copy of data that can be returned much faster than from the source. Uygulamalar, önbelleğe alınmış verilere hiçbir şekilde bağlı olmayacak şekilde yazılmalıdır ve test edilmelidir.Apps should be written and tested to never depend on cached data.

ASP.NET Core birçok farklı önbelleği destekler.ASP.NET Core supports several different caches. En basit önbellek ımemorycache' i temel alır.The simplest cache is based on the IMemoryCache. IMemoryCache Web sunucusunun belleğinde depolanan bir önbelleği temsil eder.IMemoryCache represents a cache stored in the memory of the web server. Sunucu grubunda (birden çok sunucu) çalışan uygulamalar, bellek içi önbellek kullanılırken oturumların yapışkan olmasını sağlamalıdır.Apps running on a server farm (multiple servers) should ensure sessions are sticky when using the in-memory cache. Yapışkan oturumlar, bir istemciden gelen sonraki isteklerin aynı sunucuya gitmesini sağlar.Sticky sessions ensure that subsequent requests from a client all go to the same server. Örneğin, Azure Web Apps, sonraki tüm istekleri aynı sunucuya yönlendirmek için uygulama Isteği yönlendirme (ARR) kullanır.For example, Azure Web apps use Application Request Routing (ARR) to route all subsequent requests to the same server.

Bir Web grubundaki yapışkan olmayan oturumlar, önbellek tutarlılığı sorunlarından kaçınmak için Dağıtılmış bir önbellek gerektirir.Non-sticky sessions in a web farm require a distributed cache to avoid cache consistency problems. Bazı uygulamalarda, dağıtılmış bir önbellek, bellek içi bir önbellekten daha yüksek genişleme desteği sağlayabilir.For some apps, a distributed cache can support higher scale-out than an in-memory cache. Dağıtılmış bir önbellek kullanmak önbellek belleğini bir dış işleme devreder.Using a distributed cache offloads the cache memory to an external process.

Bellek içi önbellek herhangi bir nesneyi depolayabilirler.The in-memory cache can store any object. Dağıtılmış önbellek arabirimi ile sınırlıdır byte[] .The distributed cache interface is limited to byte[]. Bellek içi ve dağıtılmış önbellek deposu öğeleri anahtar-değer çiftleri olarak önbelleğe alma.The in-memory and distributed cache store cache items as key-value pairs.

System. Runtime. Caching/MemoryCacheSystem.Runtime.Caching/MemoryCache

System.Runtime.Caching/MemoryCache (NuGet paketi) ile birlikte kullanılabilir:System.Runtime.Caching/MemoryCache (NuGet package) can be used with:

  • .NET Standard 2,0 veya üzeri..NET Standard 2.0 or later.
  • .NET Standard 2,0 veya sonraki bir sürümü hedefleyen tüm .NET uygulamaları .Any .NET implementation that targets .NET Standard 2.0 or later. Örneğin, 2,0 veya üzeri ASP.NET Core.For example, ASP.NET Core 2.0 or later.
  • .NET Framework 4,5 veya üzeri..NET Framework 4.5 or later.

/ IMemoryCache System.Runtime.Caching / MemoryCache ASP.NET Core ' ye daha iyi tümleştirildiği için Microsoft. Extensions. Caching. Memory (Bu makalede açıklanan) önerilir.Microsoft.Extensions.Caching.Memory/IMemoryCache (described in this article) is recommended over System.Runtime.Caching/MemoryCache because it's better integrated into ASP.NET Core. Örneğin, IMemoryCache ASP.NET Core bağımlılığı eklemeile yerel olarak işe yarar.For example, IMemoryCache works natively with ASP.NET Core dependency injection.

System.Runtime.Caching / MemoryCache Kodu ASP.NET 4. x konumundan ASP.NET Core taşıma sırasında uyumluluk Köprüsü olarak kullanın.Use System.Runtime.Caching/MemoryCache as a compatibility bridge when porting code from ASP.NET 4.x to ASP.NET Core.

Önbellek yönergeleriCache guidelines

  • Kodun, verileri getirmek için her zaman bir geri dönüş seçeneği olmalıdır ve kullanılabilir önbelleğe alınmış bir değere bağlı değildir .Code should always have a fallback option to fetch data and not depend on a cached value being available.
  • Önbellek bir nadir kaynağı, bellek kullanır.The cache uses a scarce resource, memory. Önbellek büyümesini sınırla:Limit cache growth:

Imemorycache kullanUse IMemoryCache

Uyarı

Bağımlılık ekleme ve arama SetSize , ya da önbellek boyutunu sınırlamak için paylaşılan bellek önbelleğinin kullanılması Size SizeLimit uygulamanın başarısız olmasına neden olabilir.Using a shared memory cache from Dependency Injection and calling SetSize, Size, or SizeLimit to limit cache size can cause the app to fail. Önbellekte bir boyut sınırı ayarlandığında, tüm girişlerin eklenmekte olan bir boyut belirtmesi gerekir.When a size limit is set on a cache, all entries must specify a size when being added. Bu, geliştiricilerin paylaşılan önbelleğin kullanıldığı ilgili tam denetime sahip olmaması nedeniyle sorunlara yol açabilir.This can lead to issues since developers may not have full control on what uses the shared cache. Örneğin, Entity Framework Core paylaşılan önbelleği kullanır ve bir boyut belirtmez.For example, Entity Framework Core uses the shared cache and does not specify a size. Bir uygulama önbellek boyutu sınırı ayarlarsa ve EF Core kullanıyorsa, uygulama bir oluşturur InvalidOperationException .If an app sets a cache size limit and uses EF Core, the app throws an InvalidOperationException. ,, SetSize Size Veya SizeLimit önbelleğini sınırlandırmak için, önbelleğe alma için tek bir önbellek oluşturun.When using SetSize, Size, or SizeLimit to limit cache, create a cache singleton for caching. Daha fazla bilgi ve bir örnek için bkz. önbellek boyutunu sınırlamak Için SetSize, size ve SizeLimit kullanma.For more information and an example, see Use SetSize, Size, and SizeLimit to limit cache size. Paylaşılan bir önbellek, diğer çerçeveler veya kitaplıklar tarafından paylaşılır.A shared cache is one shared by other frameworks or libraries. Örneğin, EF Core paylaşılan önbelleği kullanır ve bir boyut belirtmez.For example, EF Core uses the shared cache and does not specify a size.

Bellek içi önbelleğe alma, bağımlılık eklemekullanılarak bir uygulamadan başvurulan bir hizmettir .In-memory caching is a service that's referenced from an app using Dependency Injection. IMemoryCacheÖrneği oluşturucuda iste:Request the IMemoryCache instance in the constructor:

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 TryGetValue kullanır.The following code uses TryGetValue to check if a time is in the cache. Bir zaman önbelleğe alınmadıysa, yeni bir giriş oluşturulur ve Ayarlabirlikte önbelleğe eklenir.If a time isn't cached, a new entry is created and added to the cache with Set. CacheKeysSınıf, indirme örneğinin bir parçasıdır.The CacheKeys class is part of the download sample.

public static class CacheKeys
{
    public static string Entry { get { return "_Entry"; } }
    public static string CallbackEntry { get { return "_Callback"; } }
    public static string CallbackMessage { get { return "_CallbackMessage"; } }
    public static string Parent { get { return "_Parent"; } }
    public static string Child { get { return "_Child"; } }
    public static string DependentMessage { get { return "_DependentMessage"; } }
    public static string DependentCTS { get { return "_DependentCTS"; } }
    public static string Ticks { get { return "_Ticks"; } }
    public static string CancelMsg { get { return "_CancelMsg"; } }
    public static string CancelTokenSource { get { return "_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ınmış saat görüntülenir:The current time and the cached time are displayed:

@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, nesneyi oluşturmadan göreli bir süre için verileri önbelleğe almak üzere set genişletme yöntemini kullanır MemoryCacheEntryOptions .The following code uses the Set extension method to cache data for a relative time without creating the MemoryCacheEntryOptions object.

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);
}

DateTimeZaman aşımı süresi içinde istekler varken önbelleğe alınan değer önbellekte kalır.The cached DateTime value remains in the cache while there are requests within the timeout period.

Aşağıdaki kod, verileri önbelleğe almak için GetOrCreate ve Getorcreateasync kullanır.The following code uses GetOrCreate and GetOrCreateAsync to cache data.

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);
}

Aşağıdaki kod, önbelleğe alınmış zamanı getirmek için Al yöntemini çağırır:The following code calls Get to fetch the cached time:

public IActionResult CacheGet()
{
    var cacheEntry = _cache.Get<DateTime?>(CacheKeys.Entry);
    return View("Cache", cacheEntry);
}

Aşağıdaki kod, mutlak süre sonu ile önbelleğe alınmış bir öğe alır veya oluşturur:The following code gets or creates a cached item with absolute expiration:

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 bir süre sonu olan önbelleğe alınmış bir öğe kümesi, eski olma riski altında.A cached item set with a sliding expiration only is at risk of becoming stale. Kayan süre sonu aralığından daha sık erişiliyorsa, öğe hiçbir zaman sona ermez.If it's accessed more frequently than the sliding expiration interval, the item will never expire. Mutlak süre sonu zamanı başarılı olduktan sonra öğenin süresinin dolacağını garantilemek için kayan bir süre sonu mutlak bir süre sonu ile birleştirin.Combine a sliding expiration with an absolute expiration to guarantee that the item expires once its absolute expiration time passes. Mutlak süre sonu, öğenin, Kayan süre sonu aralığı içinde istenmediğinde daha önce süresinin dolmasına izin verirken öğenin ne kadar süre önbellekte önbelleğe alınacağını belirleyen bir üst sınır ayarlar.The absolute expiration sets an upper bound to how long the item can be cached while still allowing the item to expire earlier if it isn't requested within the sliding expiration interval. Mutlak ve kayan süre sonu belirtildiğinde, süre sonları mantıksal ORed.When both absolute and sliding expiration are specified, the expirations are logically ORed. Kayan süre sonu aralığı veya mutlak süre sonu zamanı başarılı olursa, öğe önbellekten çıkarıldı.If either the sliding expiration interval or the absolute expiration time pass, the item is evicted from the cache.

Aşağıdaki kod hem kayan hem de mutlak süre sonu ile önbelleğe alınmış bir öğe alır veya oluşturur:The following code gets or creates a cached item with both sliding and absolute expiration:

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ınmamasını garanti eder.The preceding code guarantees the data will not be cached longer than the absolute time.

GetOrCreate, GetOrCreateAsync ve, Get sınıfında uzantı yöntemleridir CacheExtensions .GetOrCreate, GetOrCreateAsync, and Get are extension methods in the CacheExtensions class. Bu yöntemler kapasitesini genişletir IMemoryCache .These methods extend the capability of IMemoryCache.

MemoryCacheEntryOptions

Aşağıdaki örnek:The following sample:

  • Kayan süre sonu zamanı ayarlar.Sets a sliding expiration time. Bu önbelleğe alınmış öğeye erişen istekler, Kayan süre sonu saatini sıfırlayacaktır.Requests that access this cached item will reset the sliding expiration clock.
  • Önbellek önceliğini Cacheitempriınıd. NeverRemoveolarak ayarlar.Sets the cache priority to CacheItemPriority.NeverRemove.
  • Giriş önbellekten çıkarıldıktan sonra çağrılacak Postevictiondelegate ayarlar.Sets a PostEvictionDelegate that will be called after the entry is evicted from the cache. Geri çağırma, öğeyi önbellekten kaldıran koddan farklı bir iş parçacığında çalıştırılır.The callback is run on a different thread from the code that removes the item from the cache.
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 kullanınUse SetSize, Size, and SizeLimit to limit cache size

MemoryCacheÖrnek, isteğe bağlı olarak bir boyut sınırı belirtebilir ve uygulayabilir.A MemoryCache instance may optionally specify and enforce a size limit. Önbelleğin, girdilerin boyutunu ölçmeye yönelik bir mekanizması olmadığından, önbellek boyutu sınırının tanımlı bir ölçü birimi yok.The cache size limit does not have a defined unit of measure because the cache has no mechanism to measure the size of entries. Önbellek boyutu sınırı ayarlandıysa, tüm girişlerin boyut belirtmesi gerekir.If the cache size limit is set, all entries must specify size. ASP.NET Core çalışma zamanı, bellek baskısı temelinde önbellek boyutunu sınırlamaz.The ASP.NET Core runtime does not limit cache size based on memory pressure. En fazla geliştirici, önbellek boyutunu sınırlayacak.It's up to the developer to limit cache size. Belirtilen boyut, geliştiricinin seçtiği birimlerde bulunur.The size specified is in units the developer chooses.

Örnek:For example:

  • Web uygulaması öncelikle dizeleri önbelleğe alıyorsa, her önbellek girdisi boyutu dize uzunluğu olabilir.If the web app was primarily caching strings, each cache entry size could be the string length.
  • Uygulama tüm girdilerin boyutunu 1 olarak belirtebilir ve boyut sınırı girdi sayısıdır.The app could specify the size of all entries as 1, and the size limit is the count of entries.

SizeLimitAyarlanmamışsa, önbellek bağlantılı olmadan büyür.If SizeLimit isn't set, the cache grows without bound. ASP.NET Core çalışma zamanı, sistem belleği azaldığında önbelleği kırpmaz.The ASP.NET Core runtime doesn't trim the cache when system memory is low. Uygulamalar şu şekilde tasarlanmış olmalıdır:Apps must be architected to:

  • Önbellek büyümesini sınırla.Limit cache growth.
  • CompactKullanılabilir bellek için arama veya Remove zaman sınırlı olduğunda:Call Compact or Remove when available memory is limited:

Aşağıdaki kod, MemoryCache bağımlılık eklemetarafından erişilebilen bir unitless sabit boyutu oluşturur:The following code creates a unitless fixed size MemoryCache accessible by dependency injection:

// using Microsoft.Extensions.Caching.Memory;
public class MyMemoryCache 
{
    public MemoryCache Cache { get; set; }
    public MyMemoryCache()
    {
        Cache = new MemoryCache(new MemoryCacheOptions
        {
            SizeLimit = 1024
        });
    }
}

SizeLimit birimleri yok.SizeLimit does not have units. Önbellek boyutu sınırı ayarlandıysa, önbelleğe alınmış girişler, en çok ne kadar uygun olduğunu belirleyen birimlerde boyut belirtmelidir.Cached entries must specify size in whatever units they deem most appropriate if the cache size limit has been set. Bir önbellek örneğinin tüm kullanıcıları aynı birim sistemini kullanmalıdır.All users of a cache instance should use the same unit system. Önbelleğe alınmış giriş boyutlarının toplamı tarafından belirtilen değeri aşarsa, bir giriş önbelleğe alınmaz SizeLimit .An entry will not be cached if the sum of the cached entry sizes exceeds the value specified by SizeLimit. Önbellek boyutu sınırı ayarlanmamışsa, girişte ayarlanan önbellek boyutu yok sayılır.If no cache size limit is set, the cache size set on the entry will be ignored.

Aşağıdaki kod, MyMemoryCache bağımlılık ekleme kapsayıcısına kaydolur.The following code registers MyMemoryCache with the dependency injection container.

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
    services.AddSingleton<MyMemoryCache>();
}

MyMemoryCache , bu boyut sınırlı önbelleğin farkında olan bileşenler için bağımsız bir bellek önbelleği olarak oluşturulur ve önbellek girişi boyutunu uygun şekilde ayarlamayı öğrenin.MyMemoryCache is created as an independent memory cache for components that are aware of this size limited cache and know how to set cache entry size appropriately.

Aşağıdaki kod şunu kullanır MyMemoryCache :The following code uses 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 girişinin boyutu Size veya SetSize genişletme yöntemleriyle ayarlanabilir:The size of the cache entry can be set by Size or the SetSize extension methods:

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. CompactMemoryCache.Compact

MemoryCache.Compact aşağıdaki sırada önbelleğin belirtilen yüzdesini kaldırmaya çalışır:MemoryCache.Compact attempts to remove the specified percentage of the cache in the following order:

  • Tüm süre dolmamış öğeler.All expired items.
  • Önceliğe göre öğeler.Items by priority. Önce en düşük öncelik öğeleri kaldırılır.Lowest priority items are removed first.
  • En son kullanılan nesneler.Least recently used objects.
  • En erken mutlak bitiş tarihi olan öğeler.Items with the earliest absolute expiration.
  • En erken Kayan süre sonu olan öğeler.Items with the earliest sliding expiration.

Önceliğe sahip sabitlenmiş öğeler NeverRemove hiçbir şekilde kaldırılmaz.Pinned items with priority NeverRemove are never removed. Aşağıdaki kod bir önbellek öğesini ve çağrılarını kaldırır Compact :The following code removes a cache item and calls Compact:

_cache.Remove(MyKey);

// Remove 33% of cached items.
_cache.Compact(.33);   
cache_size = _cache.Count;

Daha fazla bilgi için bkz. GitHub 'Da Compact Source .See Compact source on GitHub for more information.

Önbellek bağımlılıklarıCache dependencies

Aşağıdaki örnek, bağımlı bir girdinin süresi dolduğunda önbellek girişinin süresinin dolacağını gösterir.The following sample shows how to expire a cache entry if a dependent entry expires. CancellationChangeTokenÖnbelleğe alınmış öğeye eklenir.A CancellationChangeToken is added to the cached item. CancelÜzerinde çağrıldığında CancellationTokenSource , her iki önbellek girişi de çıkarıldı.When Cancel is called on the CancellationTokenSource, both cache entries are evicted.

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);
}

Kullanmak, CancellationTokenSource birden çok önbellek girişinin bir grup olarak çıkarıyapılmasına izin verir.Using a CancellationTokenSource allows multiple cache entries to be evicted as a group. usingYukarıdaki koddaki örüntüle, blok içinde oluşturulan önbellek girdileri using Tetikleyiciler ve süre sonu ayarlarını devralacak.With the using pattern in the code above, cache entries created inside the using block will inherit triggers and expiration settings.

Ek notlarAdditional notes

  • Süre sonu arka planda gerçekleşmez.Expiration doesn't happen in the background. Süre dolmakta olan öğeler için önbelleği etkin bir şekilde tarayan bir Zamanlayıcı yok.There is no timer that actively scans the cache for expired items. Önbellekteki herhangi bir etkinlik ( Get , Set , Remove ), zaman aşımına uğradı öğeler için bir arka plan taraması tetikleyebilir.Any activity on the cache (Get, Set, Remove) can trigger a background scan for expired items. () Üzerindeki bir CancellationTokenSource Zamanlayıcı CancelAfter Ayrıca girişi kaldırır ve vadesi geçmiş öğeler için bir tarama tetikler.A timer on the CancellationTokenSource (CancelAfter) also removes the entry and triggers a scan for expired items. Aşağıdaki örnek, kayıtlı belirteç için CancellationTokenSource (TimeSpan) kullanır.The following example uses CancellationTokenSource(TimeSpan) for the registered token. Bu belirteç tetiklendiğinde, girdiyi hemen kaldırır ve çıkarma geri çağırmaları tetikler:When this token fires it removes the entry immediately and fires the eviction callbacks:
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);
}
  • Bir önbellek öğesini yeniden doldurmak için geri çağırma kullanırken:When using a callback to repopulate a cache item:

    • Geri arama tamamlanmadığından, birden çok istek önbelleğe alınan anahtar değeri boş olabilir.Multiple requests can find the cached key value empty because the callback hasn't completed.
    • Bu, birden çok iş parçacığının önbelleğe alınan öğeyi yeniden doldurma ile sonuçlanabilir.This can result in several threads repopulating the cached item.
  • Diğeri oluşturmak için bir önbellek girdisi kullanıldığında, alt öğe üst girdinin süre sonu belirteçlerini ve zaman tabanlı süre sonu ayarlarını kopyalar.When one cache entry is used to create another, the child copies the parent entry's expiration tokens and time-based expiration settings. Üst girdinin el ile kaldırılması veya güncelleştirilmesi için alt öğenin kullanım dışı olmaması.The child isn't expired by manual removal or updating of the parent entry.

  • PostEvictionCallbacksÖnbellek girdisi önbellekten çıkarıldıktan sonra uygulanacak geri çağırmaları ayarlamak için kullanın.Use PostEvictionCallbacks to set the callbacks that will be fired after the cache entry is evicted from the cache.

  • Çoğu uygulama için IMemoryCache etkindir.For most apps, IMemoryCache is enabled. Örneğin,,, AddMvc , AddControllersWithViews AddRazorPages AddMvcCore().AddRazorViewEngine ve diğer birçok yöntemi ' de Add{Service} ConfigureServices IMemoryCache çağırarak, ' ı etkinleştirilir.For example, calling AddMvc, AddControllersWithViews, AddRazorPages, AddMvcCore().AddRazorViewEngine, and many other Add{Service} methods in ConfigureServices, enables IMemoryCache. Önceki yöntemlerden birini çağırmayan uygulamalarda ' Add{Service} de çağrılması gerekebilir AddMemoryCache ConfigureServices .For apps that are not calling one of the preceding Add{Service} methods, it may be necessary to call AddMemoryCache in ConfigureServices.

Arka plan önbelleği güncelleştirmesiBackground cache update

Önbelleği güncelleştirmek için gibi bir arka plan hizmeti kullanın IHostedService .Use a background service such as IHostedService to update the cache. Arka plan hizmeti, girdileri yeniden hesaplar ve ardından bunları yalnızca kullanılabilir olduğunda önbelleğe atayabilir.The background service can recompute the entries and then assign them to the cache only when they’re ready.

Ek kaynaklarAdditional resources

By Rick Anderson, John Luove Steve SmithBy Rick Anderson, John Luo, and Steve Smith

Örnek kodu görüntüleme veya indirme (nasıl indirileceği)View or download sample code (how to download)

Önbelleğe alma temelleriCaching basics

Önbelleğe alma, içerik oluşturmak için gereken işi azaltarak bir uygulamanın performansını ve ölçeklenebilirliğini önemli ölçüde iyileştirebilir.Caching can significantly improve the performance and scalability of an app by reducing the work required to generate content. Önbelleğe alma, seyrek olarak değişen verilerle en iyi şekilde sonuç verir.Caching works best with data that changes infrequently. Önbelleğe alma, özgün kaynaktan çok daha hızlı döndürülebilecek verilerin bir kopyasını oluşturur.Caching makes a copy of data that can be returned much faster than from the original source. Kod, önbelleğe alınmış verilere hiçbir şekilde bağlı olmayacak şekilde yazılmalıdır ve test edilmelidir.Code should be written and tested to never depend on cached data.

ASP.NET Core birçok farklı önbelleği destekler.ASP.NET Core supports several different caches. En basit önbellek, Web sunucusunun belleğinde depolanan bir önbelleği temsil eden ımemorycache' i temel alır.The simplest cache is based on the IMemoryCache, which represents a cache stored in the memory of the web server. Sunucu grubunda çalışan uygulamalar (birden çok sunucu), bellek içi önbellek kullanılırken oturumların yapışkan olmasını sağlamalıdır.Apps that run on a server farm (multiple servers) should ensure that sessions are sticky when using the in-memory cache. Yapışkan oturumlar, bir istemciden sonraki isteklerin aynı sunucuya gitmesini sağlar.Sticky sessions ensure that later requests from a client all go to the same server. Örneğin, Azure Web Apps, bir Kullanıcı aracısından tüm istekleri aynı sunucuya yönlendirmek için uygulama Isteği yönlendirme (ARR) kullanır.For example, Azure Web apps use Application Request Routing (ARR) to route all requests from a user agent to the same server.

Bir Web grubundaki yapışkan olmayan oturumlar, önbellek tutarlılığı sorunlarından kaçınmak için Dağıtılmış bir önbellek gerektirir.Non-sticky sessions in a web farm require a distributed cache to avoid cache consistency problems. Bazı uygulamalarda, dağıtılmış bir önbellek, bellek içi bir önbellekten daha yüksek genişleme desteği sağlayabilir.For some apps, a distributed cache can support higher scale-out than an in-memory cache. Dağıtılmış bir önbellek kullanmak önbellek belleğini bir dış işleme devreder.Using a distributed cache offloads the cache memory to an external process.

Bellek içi önbellek herhangi bir nesneyi depolayabilirler.The in-memory cache can store any object. Dağıtılmış önbellek arabirimi ile sınırlıdır byte[] .The distributed cache interface is limited to byte[]. Bellek içi ve dağıtılmış önbellek deposu öğeleri anahtar-değer çiftleri olarak önbelleğe alma.The in-memory and distributed cache store cache items as key-value pairs.

System. Runtime. Caching/MemoryCacheSystem.Runtime.Caching/MemoryCache

System.Runtime.Caching/MemoryCache (NuGet paketi) ile birlikte kullanılabilir:System.Runtime.Caching/MemoryCache (NuGet package) can be used with:

  • .NET Standard 2,0 veya üzeri..NET Standard 2.0 or later.
  • .NET Standard 2,0 veya sonraki bir sürümü hedefleyen tüm .NET uygulamaları .Any .NET implementation that targets .NET Standard 2.0 or later. Örneğin, 2,0 veya üzeri ASP.NET Core.For example, ASP.NET Core 2.0 or later.
  • .NET Framework 4,5 veya üzeri..NET Framework 4.5 or later.

/ IMemoryCache System.Runtime.Caching / MemoryCache ASP.NET Core ' ye daha iyi tümleştirildiği için Microsoft. Extensions. Caching. Memory (Bu makalede açıklanan) önerilir.Microsoft.Extensions.Caching.Memory/IMemoryCache (described in this article) is recommended over System.Runtime.Caching/MemoryCache because it's better integrated into ASP.NET Core. Örneğin, IMemoryCache ASP.NET Core bağımlılığı eklemeile yerel olarak işe yarar.For example, IMemoryCache works natively with ASP.NET Core dependency injection.

System.Runtime.Caching / MemoryCache Kodu ASP.NET 4. x konumundan ASP.NET Core taşıma sırasında uyumluluk Köprüsü olarak kullanın.Use System.Runtime.Caching/MemoryCache as a compatibility bridge when porting code from ASP.NET 4.x to ASP.NET Core.

Önbellek yönergeleriCache guidelines

  • Kodun, verileri getirmek için her zaman bir geri dönüş seçeneği olmalıdır ve kullanılabilir önbelleğe alınmış bir değere bağlı değildir .Code should always have a fallback option to fetch data and not depend on a cached value being available.
  • Önbellek bir nadir kaynağı, bellek kullanır.The cache uses a scarce resource, memory. Önbellek büyümesini sınırla:Limit cache growth:

Imemorycache kullanmaUsing IMemoryCache

Uyarı

Bağımlılık ekleme ve arama SetSize , ya da önbellek boyutunu sınırlamak için paylaşılan bellek önbelleğinin kullanılması Size SizeLimit uygulamanın başarısız olmasına neden olabilir.Using a shared memory cache from Dependency Injection and calling SetSize, Size, or SizeLimit to limit cache size can cause the app to fail. Önbellekte bir boyut sınırı ayarlandığında, tüm girişlerin eklenmekte olan bir boyut belirtmesi gerekir.When a size limit is set on a cache, all entries must specify a size when being added. Bu, geliştiricilerin paylaşılan önbelleğin kullanıldığı ilgili tam denetime sahip olmaması nedeniyle sorunlara yol açabilir.This can lead to issues since developers may not have full control on what uses the shared cache. Örneğin, Entity Framework Core paylaşılan önbelleği kullanır ve bir boyut belirtmez.For example, Entity Framework Core uses the shared cache and does not specify a size. Bir uygulama önbellek boyutu sınırı ayarlarsa ve EF Core kullanıyorsa, uygulama bir oluşturur InvalidOperationException .If an app sets a cache size limit and uses EF Core, the app throws an InvalidOperationException. ,, SetSize Size Veya SizeLimit önbelleğini sınırlandırmak için, önbelleğe alma için tek bir önbellek oluşturun.When using SetSize, Size, or SizeLimit to limit cache, create a cache singleton for caching. Daha fazla bilgi ve bir örnek için bkz. önbellek boyutunu sınırlamak Için SetSize, size ve SizeLimit kullanma.For more information and an example, see Use SetSize, Size, and SizeLimit to limit cache size.

Bellek içi önbelleğe alma, bağımlılık eklemekullanılarak uygulamanız tarafından başvurulan bir hizmettir .In-memory caching is a service that's referenced from your app using Dependency Injection. Çağırma AddMemoryCache ConfigureServices :Call AddMemoryCache in ConfigureServices:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMemoryCache();

        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseMvcWithDefaultRoute();
    }
}

IMemoryCacheÖrneği oluşturucuda iste:Request the IMemoryCache instance in the constructor:

public class HomeController : Controller
{
    private IMemoryCache _cache;

    public HomeController(IMemoryCache memoryCache)
    {
        _cache = memoryCache;
    }

IMemoryCacheMicrosoft.AspNetCore.app metapackage'de bulunan NuGet paketi Microsoft. Extensions. Caching. Memorygerektirir.IMemoryCache requires NuGet package Microsoft.Extensions.Caching.Memory, which is available in the Microsoft.AspNetCore.App metapackage.

Aşağıdaki kod, bir saatin önbellekte olup olmadığını denetlemek için TryGetValue kullanır.The following code uses TryGetValue to check if a time is in the cache. Bir zaman önbelleğe alınmadıysa, yeni bir giriş oluşturulur ve Ayarlabirlikte önbelleğe eklenir.If a time isn't cached, a new entry is created and added to the cache with Set.

public static class CacheKeys
{
    public static string Entry { get { return "_Entry"; } }
    public static string CallbackEntry { get { return "_Callback"; } }
    public static string CallbackMessage { get { return "_CallbackMessage"; } }
    public static string Parent { get { return "_Parent"; } }
    public static string Child { get { return "_Child"; } }
    public static string DependentMessage { get { return "_DependentMessage"; } }
    public static string DependentCTS { get { return "_DependentCTS"; } }
    public static string Ticks { get { return "_Ticks"; } }
    public static string CancelMsg { get { return "_CancelMsg"; } }
    public static string CancelTokenSource { get { return "_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ınmış saat görüntülenir:The current time and the cached time are displayed:

@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="CacheGetOrCreateAsync">GetOrCreateAsync</a></li>
        <li><a asp-controller="Home" asp-action="CacheRemove">Remove</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>

DateTimeZaman aşımı süresi içinde istekler varken önbelleğe alınan değer önbellekte kalır.The cached DateTime value remains in the cache while there are requests within the timeout period. Aşağıdaki görüntüde geçerli saat ve önbellekten alınan eski bir zaman gösterilmektedir:The following image shows the current time and an older time retrieved from the cache:

İki farklı saat görüntülenirken dizin görünümü

Aşağıdaki kod, verileri önbelleğe almak için GetOrCreate ve Getorcreateasync kullanır.The following code uses GetOrCreate and GetOrCreateAsync to cache data.

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> CacheGetOrCreateAsync()
{
    var cacheEntry = await
        _cache.GetOrCreateAsync(CacheKeys.Entry, entry =>
    {
        entry.SlidingExpiration = TimeSpan.FromSeconds(3);
        return Task.FromResult(DateTime.Now);
    });

    return View("Cache", cacheEntry);
}

Aşağıdaki kod, önbelleğe alınmış zamanı getirmek için Al yöntemini çağırır:The following code calls Get to fetch the cached time:

public IActionResult CacheGet()
{
    var cacheEntry = _cache.Get<DateTime?>(CacheKeys.Entry);
    return View("Cache", cacheEntry);
}

GetOrCreate , GetOrCreateAsync ve Get , ve kapasitesini genişleten cacheextensions sınıfının bir parçası olan genişletme metodlarıdır IMemoryCache .GetOrCreate , GetOrCreateAsync, and Get are extension methods part of the CacheExtensions class that extends the capability of IMemoryCache. Diğer önbellek yöntemlerinin açıklaması için bkz. ımemorycache metotları ve cacheextensions yöntemleri .See IMemoryCache methods and CacheExtensions methods for a description of other cache methods.

Memorycachebir YoptionsMemoryCacheEntryOptions

Aşağıdaki örnek:The following sample:

  • Kayan süre sonu zamanı ayarlar.Sets a sliding expiration time. Bu önbelleğe alınmış öğeye erişen istekler, Kayan süre sonu saatini sıfırlayacaktır.Requests that access this cached item will reset the sliding expiration clock.
  • Önbellek önceliğini olarak ayarlar CacheItemPriority.NeverRemove .Sets the cache priority to CacheItemPriority.NeverRemove.
  • Giriş önbellekten çıkarıldıktan sonra çağrılacak Postevictiondelegate ayarlar.Sets a PostEvictionDelegate that will be called after the entry is evicted from the cache. Geri çağırma, öğeyi önbellekten kaldıran koddan farklı bir iş parçacığında çalıştırılır.The callback is run on a different thread from the code that removes the item from the cache.
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 kullanınUse SetSize, Size, and SizeLimit to limit cache size

MemoryCacheÖrnek, isteğe bağlı olarak bir boyut sınırı belirtebilir ve uygulayabilir.A MemoryCache instance may optionally specify and enforce a size limit. Önbelleğin, girdilerin boyutunu ölçmeye yönelik bir mekanizması olmadığından, önbellek boyutu sınırının tanımlı bir ölçü birimi yok.The cache size limit does not have a defined unit of measure because the cache has no mechanism to measure the size of entries. Önbellek boyutu sınırı ayarlandıysa, tüm girişlerin boyut belirtmesi gerekir.If the cache size limit is set, all entries must specify size. ASP.NET Core çalışma zamanı, bellek baskısı temelinde önbellek boyutunu sınırlamaz.The ASP.NET Core runtime does not limit cache size based on memory pressure. En fazla geliştirici, önbellek boyutunu sınırlayacak.It's up to the developer to limit cache size. Belirtilen boyut, geliştiricinin seçtiği birimlerde bulunur.The size specified is in units the developer chooses.

Örnek:For example:

  • Web uygulaması öncelikle dizeleri önbelleğe alıyorsa, her önbellek girdisi boyutu dize uzunluğu olabilir.If the web app was primarily caching strings, each cache entry size could be the string length.
  • Uygulama tüm girdilerin boyutunu 1 olarak belirtebilir ve boyut sınırı girdi sayısıdır.The app could specify the size of all entries as 1, and the size limit is the count of entries.

SizeLimitAyarlanmamışsa, önbellek bağlantılı olmadan büyür.If SizeLimit is not set, the cache grows without bound. ASP.NET Core çalışma zamanı, sistem belleği azaldığında önbelleği kırpmaz.The ASP.NET Core runtime does not trim the cache when system memory is low. Uygulamalar şu şekilde tasarlanmıştır:Apps much be architected to:

  • Önbellek büyümesini sınırla.Limit cache growth.
  • CompactKullanılabilir bellek için arama veya Remove zaman sınırlı olduğunda:Call Compact or Remove when available memory is limited:

Aşağıdaki kod, MemoryCache bağımlılık eklemetarafından erişilebilen bir unitless sabit boyutu oluşturur:The following code creates a unitless fixed size MemoryCache accessible by dependency injection:

// using Microsoft.Extensions.Caching.Memory;
public class MyMemoryCache 
{
    public MemoryCache Cache { get; set; }
    public MyMemoryCache()
    {
        Cache = new MemoryCache(new MemoryCacheOptions
        {
            SizeLimit = 1024
        });
    }
}

SizeLimit birimleri yok.SizeLimit does not have units. Önbellek boyutu sınırı ayarlandıysa, önbelleğe alınmış girişler, en çok ne kadar uygun olduğunu belirleyen birimlerde boyut belirtmelidir.Cached entries must specify size in whatever units they deem most appropriate if the cache size limit has been set. Bir önbellek örneğinin tüm kullanıcıları aynı birim sistemini kullanmalıdır.All users of a cache instance should use the same unit system. Önbelleğe alınmış giriş boyutlarının toplamı tarafından belirtilen değeri aşarsa, bir giriş önbelleğe alınmaz SizeLimit .An entry will not be cached if the sum of the cached entry sizes exceeds the value specified by SizeLimit. Önbellek boyutu sınırı ayarlanmamışsa, girişte ayarlanan önbellek boyutu yok sayılır.If no cache size limit is set, the cache size set on the entry will be ignored.

Aşağıdaki kod, MyMemoryCache bağımlılık ekleme kapsayıcısına kaydolur.The following code registers MyMemoryCache with the dependency injection container.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

    services.AddSingleton<MyMemoryCache>();
}

MyMemoryCache , bu boyut sınırlı önbelleğin farkında olan bileşenler için bağımsız bir bellek önbelleği olarak oluşturulur ve önbellek girişi boyutunu uygun şekilde ayarlamayı öğrenin.MyMemoryCache is created as an independent memory cache for components that are aware of this size limited cache and know how to set cache entry size appropriately.

Aşağıdaki kod şunu kullanır MyMemoryCache :The following code uses MyMemoryCache:

public class AboutModel : PageModel
{
    private MemoryCache _cache;
    public static readonly string MyKey = "_MyKey";

    public AboutModel(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 girişinin boyutu boyuta veya SetSize uzantı yöntemine göre ayarlanabilir:The size of the cache entry can be set by Size or the SetSize extension method:

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. CompactMemoryCache.Compact

MemoryCache.Compact aşağıdaki sırada önbelleğin belirtilen yüzdesini kaldırmaya çalışır:MemoryCache.Compact attempts to remove the specified percentage of the cache in the following order:

  • Tüm süre dolmamış öğeler.All expired items.
  • Önceliğe göre öğeler.Items by priority. Önce en düşük öncelik öğeleri kaldırılır.Lowest priority items are removed first.
  • En son kullanılan nesneler.Least recently used objects.
  • En erken mutlak bitiş tarihi olan öğeler.Items with the earliest absolute expiration.
  • En erken Kayan süre sonu olan öğeler.Items with the earliest sliding expiration.

Önceliğe sahip sabitlenmiş öğeler NeverRemove hiçbir şekilde kaldırılmaz.Pinned items with priority NeverRemove are never removed.

_cache.Remove(MyKey);

// Remove 33% of cached items.
_cache.Compact(.33);   
cache_size = _cache.Count;

Daha fazla bilgi için bkz. GitHub 'Da Compact Source .See Compact source on GitHub for more information.

Önbellek bağımlılıklarıCache dependencies

Aşağıdaki örnek, bağımlı bir girdinin süresi dolduğunda önbellek girişinin süresinin dolacağını gösterir.The following sample shows how to expire a cache entry if a dependent entry expires. CancellationChangeTokenÖnbelleğe alınmış öğeye eklenir.A CancellationChangeToken is added to the cached item. CancelÜzerinde çağrıldığında CancellationTokenSource , her iki önbellek girişi de çıkarıldı.When Cancel is called on the CancellationTokenSource, both cache entries are evicted.

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);
}

Kullanmak, CancellationTokenSource birden çok önbellek girişinin bir grup olarak çıkarıyapılmasına izin verir.Using a CancellationTokenSource allows multiple cache entries to be evicted as a group. usingYukarıdaki koddaki örüntüle, blok içinde oluşturulan önbellek girdileri using Tetikleyiciler ve süre sonu ayarlarını devralacak.With the using pattern in the code above, cache entries created inside the using block will inherit triggers and expiration settings.

Ek notlarAdditional notes

  • Bir önbellek öğesini yeniden doldurmak için geri çağırma kullanırken:When using a callback to repopulate a cache item:

    • Geri arama tamamlanmadığından, birden çok istek önbelleğe alınan anahtar değeri boş olabilir.Multiple requests can find the cached key value empty because the callback hasn't completed.
    • Bu, birden çok iş parçacığının önbelleğe alınan öğeyi yeniden doldurma ile sonuçlanabilir.This can result in several threads repopulating the cached item.
  • Diğeri oluşturmak için bir önbellek girdisi kullanıldığında, alt öğe üst girdinin süre sonu belirteçlerini ve zaman tabanlı süre sonu ayarlarını kopyalar.When one cache entry is used to create another, the child copies the parent entry's expiration tokens and time-based expiration settings. Üst girdinin el ile kaldırılması veya güncelleştirilmesi için alt öğenin kullanım dışı olmaması.The child isn't expired by manual removal or updating of the parent entry.

  • Önbellek girdisi önbellekten çıkarıldıktan sonra uygulanacak geri çağırmaları ayarlamak için Postevictioncallbacks kullanın.Use PostEvictionCallbacks to set the callbacks that will be fired after the cache entry is evicted from the cache.

Arka plan önbelleği güncelleştirmesiBackground cache update

Önbelleği güncelleştirmek için gibi bir arka plan hizmeti kullanın IHostedService .Use a background service such as IHostedService to update the cache. Arka plan hizmeti, girdileri yeniden hesaplar ve ardından bunları yalnızca kullanılabilir olduğunda önbelleğe atayabilir.The background service can recompute the entries and then assign them to the cache only when they’re ready.

Ek kaynaklarAdditional resources