Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Av Rick Anderson, John Luo och Steve Smith
Cachelagring kan avsevärt förbättra prestanda och skalbarhet för en app genom att minska det arbete som krävs för att generera innehåll. Cachelagring fungerar bäst med data som ändras sällan och är dyrt att generera. Cachelagring gör en kopia av data som kan returneras mycket snabbare än från källan. Appar ska skrivas och testas för att aldrig vara beroende av cachelagrade data.
ASP.NET Core stöder flera olika cacheminnen. Den enklaste cachen baseras på IMemoryCache. 
              IMemoryCache representerar en cache som lagras i webbserverns minne. Applikationer som körs på en serverfarm (flera servrar) bör se till att sessionerna är knutna när man använder minnesintern cache. Sticky-sessioner säkerställer att begäranden från en klient alla går till samma server. Till exempel använder Azure Web Apps routning av programbegäran (ARR) för att dirigera alla begäranden till samma server.
Icke-klibbiga sessioner i en webbgrupp kräver en distribuerad cache för att undvika problem med cachekonsekvens. För vissa appar kan en distribuerad cache ha stöd för högre utskalning än en minnesintern cache. Om du använder en distribuerad cache avlastas cacheminnet till en extern process.
Minnesintern cache kan lagra valfritt objekt. Det distribuerade cachegränssnittet är begränsat till byte[]. Minnesintern och distribuerad cachelagring lagrar cacheobjekt som nyckel/värde-par.
System.Runtime.Caching/MemoryCache
System.Runtime.Caching / MemoryCache (NuGet-paket) kan användas med:
- .NET Standard 2.0 eller senare.
- Alla .NET-implementeringar som är inriktade på .NET Standard 2.0 eller senare. Till exempel ASP.NET Core 3.1 eller senare.
- .NET Framework 4.5 eller senare.
              Microsoft.Extensions.Caching.Memory/IMemoryCache (beskrivs i den här artikeln) rekommenderas över System.Runtime.Caching/MemoryCache eftersom det är bättre integrerat i ASP.NET Core. Till exempel fungerar IMemoryCache naturligt med ASP.NET Core beroendeinjektion.
Använd System.Runtime.Caching/MemoryCache som en kompatibilitetsbrygga när du porterar kod från ASP.NET 4.x till ASP.NET Core.
Riktlinjer för cachelagring
- Kod bör alltid ha ett reservalternativ för att hämta data och inte vara beroende av att ett cachelagrat värde är tillgängligt.
- Cachen använder en knapp resurs, minne. Begränsa cachetillväxt: - Infoga inte externa indata i cacheminnet. Till exempel rekommenderas inte användning av godtyckliga användarindata som cachenyckel eftersom indata kan förbruka en oförutsägbar mängd minne.
- Använd förfallodatum för att begränsa cachetillväxten.
- Använd SetSize, Size och SizeLimit för att begränsa cachestorleken. ASP.NET Core-körningen begränsar inte cachestorleken baserat på minnesbelastning. Det är upp till utvecklaren att begränsa cachestorleken.
 
Använda IMemoryCache
Warning
Om du använder en delad minnescache från Beroendeinmatning och anropar SetSize, Sizeeller SizeLimit för att begränsa cachestorleken kan det leda till att appen misslyckas. När en storleksgräns har angetts för en cache måste alla poster ange en storlek när de läggs till. Detta kan leda till problem eftersom utvecklare kanske inte har fullständig kontroll över vad som använder den delade cachen.
När du använder SetSize, Sizeeller SizeLimit för att begränsa cacheminnet skapar du en cache-singleton för cachelagring. Mer information och ett exempel finns i Använda SetSize, Size och SizeLimit för att begränsa cachestorleken.
En delad cache delas av andra ramverk eller bibliotek.
Minnescache är en tjänst som refereras från en app med beroendeinjektion. Begär instansen IMemoryCache i konstruktorn:
public class IndexModel : PageModel
{
    private readonly IMemoryCache _memoryCache;
    public IndexModel(IMemoryCache memoryCache) =>
        _memoryCache = memoryCache;
    // ...
Följande kod används TryGetValue för att kontrollera om en tid finns i cacheminnet. Om en tidpunkt inte finns i cacheminnet skapas en ny post och läggs till i cacheminnet med Set:
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;
}
I föregående kod konfigureras cacheposten med en glidande förfallotid på tre sekunder. Om cacheposten inte nås på mer än tre sekunder avlägsnas den från cachen. Varje gång cacheposten används finns den kvar i cacheminnet i ytterligare 3 sekunder. Klassen CacheKeys är en del av nedladdningsexemplet.
Aktuell tid och cachelagrad tid visas:
<ul>
    <li>Current Time: @Model.CurrentDateTime</li>
    <li>Cached Time: @Model.CacheCurrentDateTime</li>
</ul>
Följande kod använder tilläggsmetoden Set för att cachelagra data under en relativ tid utan MemoryCacheEntryOptions:
_memoryCache.Set(CacheKeys.Entry, DateTime.Now, TimeSpan.FromDays(1));
I föregående kod konfigureras cacheposten med en relativ förfallotid på en dag. Cacheposten tas bort från cacheminnet efter en dag, även om den nås inom den här tidsgränsen.
Följande kod använder GetOrCreate och GetOrCreateAsync för att cachelagra data.
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);
        });
    // ...
}
Följande kod anropar Get för att hämta den cachelagrade tiden:
var cacheEntry = _memoryCache.Get<DateTime?>(CacheKeys.Entry);
Följande kod hämtar eller skapar ett cachelagrat objekt med absolut förfallotid:
var cachedValue = _memoryCache.GetOrCreate(
    CacheKeys.Entry,
    cacheEntry =>
    {
        cacheEntry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(20);
        return DateTime.Now;
    });
En cachelagrad objektuppsättning med endast en glidande förfallotid riskerar att aldrig upphöra att gälla. Om det cachelagrade objektet används upprepade gånger inom det glidande förfallointervallet upphör objektet aldrig att gälla. Kombinera en glidande förfallotid med en absolut förfallotid för att garantera att objektet upphör att gälla. Den absoluta förfallotiden anger en övre gräns för hur länge objektet kan cachelagras samtidigt som objektet kan upphöra att gälla tidigare om det inte begärs inom det glidande förfallointervallet. Om antingen det glidande förfallointervallet eller den absoluta förfallotiden passerar avlägsnas objektet från cachen.
Följande kod hämtar eller skapar ett cachelagrat objekt med både glidande och absolut förfallotid:
var cachedValue = _memoryCache.GetOrCreate(
    CacheKeys.CallbackEntry,
    cacheEntry =>
    {
        cacheEntry.SlidingExpiration = TimeSpan.FromSeconds(3);
        cacheEntry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(20);
        return DateTime.Now;
    });
Föregående kod garanterar att data inte cachelagras längre än den absoluta tiden.
GetOrCreate, GetOrCreateAsync, och Get är tilläggsmetoder i CacheExtensions klassen. Dessa metoder utökar kapaciteten hos IMemoryCache.
MemoryCacheEntryOptions
Följande exempel:
- Anger cacheprioriteten till CacheItemPriority.NeverRemove.
- Anger en PostEvictionDelegate som anropas efter att posten har avlägsnats från cacheminnet. Återanropet körs på en annan tråd än den kod som tar bort objektet från cacheminnet.
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}.");
}
Använd SetSize, Size och SizeLimit för att begränsa cachestorleken
En MemoryCache instans kan också ange och framtvinga en storleksgräns. Cachestorleksgränsen har ingen definierad måttenhet eftersom cacheminnet inte har någon mekanism för att mäta storleken på poster. Om gränsen för cachestorlek har angetts måste alla poster ange storlek. ASP.NET Core-körningen begränsar inte cachestorleken baserat på minnesbelastning. Det är upp till utvecklaren att begränsa cachestorleken. Den angivna storleken finns i enheter som utvecklaren väljer.
Till exempel:
- Om webbappen främst cachelagrade strängar, kunde storleken på varje cachepost vara stränglängden.
- Appen kan ange storleken på alla poster som 1 och storleksgränsen är antalet poster.
Om SizeLimit inte har angetts växer cachen utan bindning. ASP.NET Core-körningen trimmar inte cacheminnet när systemminnet är lågt. Appar måste utformas för att:
Följande kod skapar en enhetslös fast storlek MemoryCache som kan nås genom beroendeinmatning:
public class MyMemoryCache
{
    public MemoryCache Cache { get; } = new MemoryCache(
        new MemoryCacheOptions
        {
            SizeLimit = 1024
        });
}
              SizeLimit har inte enheter. Cachelagrade poster måste ange storlek i de enheter de anser mest lämpliga, om gränsen för cachestorlek har angetts. Alla användare av en cacheinstans bör använda samma enhetssystem. En post cachelagras inte om summan av de cachelagrade poststorlekarna överskrider det värde som anges av SizeLimit. Om ingen cachestorleksgräns har angetts ignoreras cachestorleken som angetts för posten.
Följande kod registrerar MyMemoryCache med containern för beroendeinjektion:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddSingleton<MyMemoryCache>();
              MyMemoryCache skapas som en oberoende minnescache för komponenter som är medvetna om den här storleksbegränsade cachen och vet hur du ställer in cachepoststorleken på rätt sätt.
Storleken på cacheposten kan anges med hjälp av SetSize tilläggsmetoden eller Size egenskapen:
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);
}
I föregående kod uppnår de två markerade raderna samma resultat genom att ange storleken på cacheposten. 
              SetSize tillhandahålls för enkelhetens skull vid länkning av samtal till new MemoryCacheOptions().
MemoryCache.Compact
              MemoryCache.Compact försöker ta bort den angivna procentandelen av cacheminnet i följande ordning:
- Alla objekt som har upphört att gälla.
- Objekt efter prioritet. Objekt med lägst prioritet tas bort först.
- Minst nyligen använda objekt.
- Objekt med den tidigaste absoluta förfallotiden.
- Objekt med den tidigaste glidande förfallotiden.
Fästa objekt med prioritet NeverRemovetas aldrig bort. Följande kod tar bort ett cacheobjekt och anropar Compact för att ta bort 25% cachelagrade poster:
_myMemoryCache.Cache.Remove(CacheKeys.Entry);
_myMemoryCache.Cache.Compact(.25);
Mer information finns i Den kompakta källan på GitHub.
Cacheberoenden
Följande exempel visar hur en cachepost löper ut om ett beroende objekt upphör att gälla. Ett CancellationChangeToken läggs till i det cachelagrade objektet. När Cancel anropas på CancellationTokenSourcetas båda cacheposterna bort:
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();
}
Med hjälp av en CancellationTokenSource kan flera cacheposter tas bort som en grupp. 
              using Med mönstret i koden ovan ärver cacheposter som skapats i omfånget using utlösare och förfalloinställningar.
Ytterligare kommentarer
- Förfallodatum sker inte i bakgrunden. Det finns ingen timer som aktivt söker igenom cachen efter objekt som har upphört att gälla. Alla aktiviteter i cacheminnet ( - Get,- TryGetValue,- Set,- Remove) kan utlösa en bakgrundssökning efter objekt som har upphört att gälla. En timer på- CancellationTokenSource(CancelAfter) tar också bort posten och utlöser en genomsökning efter objekt som har upphört att gälla. I följande exempel används CancellationTokenSource(TimeSpan) för den registrerade token. När denna token utlöses tar den bort posten omedelbart och utlöser borttagningsåteranropen.- 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); }
- När du använder ett återanrop för att fylla i ett cacheobjekt igen: - Flera begäranden kan upptäcka att det cachelagrade nyckelvärdet är tomt eftersom återanropet inte har slutförts.
- Detta kan resultera i flera trådar som repopulerar det cachelagrade objektet.
 
- När en cachepost används för att skapa en annan kopierar det underordnade objektet den överordnade postens förfallotoken och tidsbaserade förfalloinställningar. Det underordnade objektet har inte upphört att gälla genom manuell borttagning eller uppdatering av den överordnade posten. 
- Använd PostEvictionCallbacks för att ange återanrop som ska utlöses när cacheposten har avlägsnats från cachen. 
- För de flesta appar - IMemoryCacheär aktiverad. Om du till exempel anropar- AddMvc,- AddControllersWithViews,- AddRazorPages,- AddMvcCore().AddRazorViewEngineoch många andra- Add{Service}metoder i- Program.csaktiverar .- IMemoryCacheFör appar som inte anropar någon av ovanstående- Add{Service}metoder kan det vara nödvändigt att anropa AddMemoryCache i- Program.cs.
Uppdatering av bakgrundscache
Använd en bakgrundstjänst , till exempel IHostedService för att uppdatera cacheminnet. Bakgrundstjänsten kan beräkna om posterna och sedan tilldela dem till cacheminnet endast när de är redo.
Ytterligare resurser
- Visa eller ladda ned exempelkod (ladda ned)
- Distribuerad cachelagring i ASP.NET Core
- Identifiera ändringar med ändringstoken i ASP.NET Core
- Cachelagring av svar i ASP.NET Core
- Mellanprogram för cachelagring av svar i ASP.NET Core
- Hjälp för cachetaggen i ASP.NET Core MVC
- Tagghjälparen för distribuerad cache i ASP.NET Core
Visa eller ladda ned exempelkod (ladda ned)
Grundläggande om cachelagring
Cachelagring kan avsevärt förbättra prestanda och skalbarhet för en app genom att minska det arbete som krävs för att generera innehåll. Cachelagring fungerar bäst med data som ändras sällan och är dyrt att generera. Cachelagring gör en kopia av data som kan returneras mycket snabbare än från källan. Appar ska skrivas och testas för att aldrig vara beroende av cachelagrade data.
ASP.NET Core stöder flera olika cacheminnen. Den enklaste cachen baseras på IMemoryCache. 
              IMemoryCache representerar en cache som lagras i webbserverns minne. Applikationer som körs på en serverfarm (flera servrar) bör se till att sessionerna är knutna när man använder minnesintern cache. Sticky-sessioner säkerställer att efterföljande begäranden från en klient alla går till samma server. Till exempel använder Azure-webbappar routning av programbegäran (ARR) för att dirigera alla efterföljande begäranden till samma server.
Icke-klibbiga sessioner i en webbgrupp kräver en distribuerad cache för att undvika problem med cachekonsekvens. För vissa appar kan en distribuerad cache ha stöd för högre utskalning än en minnesintern cache. Om du använder en distribuerad cache avlastas cacheminnet till en extern process.
Minnesintern cache kan lagra valfritt objekt. Det distribuerade cachegränssnittet är begränsat till byte[]. Minnesintern och distribuerad cachelagring lagrar cacheobjekt som nyckel/värde-par.
System.Runtime.Caching/MemoryCache
System.Runtime.Caching / MemoryCache (NuGet-paket) kan användas med:
- .NET Standard 2.0 eller senare.
- Alla .NET-implementeringar som är inriktade på .NET Standard 2.0 eller senare. Till exempel ASP.NET Core 3.1 eller senare.
- .NET Framework 4.5 eller senare.
              Microsoft.Extensions.Caching.Memory/IMemoryCache (beskrivs i den här artikeln) rekommenderas över System.Runtime.Caching/MemoryCache eftersom det är bättre integrerat i ASP.NET Core. Till exempel fungerar IMemoryCache naturligt med ASP.NET Core beroendeinjektion.
Använd System.Runtime.Caching/MemoryCache som en kompatibilitetsbrygga när du porterar kod från ASP.NET 4.x till ASP.NET Core.
Riktlinjer för cachelagring
- Kod bör alltid ha ett reservalternativ för att hämta data och inte vara beroende av att ett cachelagrat värde är tillgängligt.
- Cachen använder en knapp resurs, minne. Begränsa cachetillväxt: - Använd inte externa indata som cachenycklar.
- Använd förfallodatum för att begränsa cachetillväxten.
- Använd SetSize, Size och SizeLimit för att begränsa cachestorleken. ASP.NET Core-körningen begränsar inte cachestorleken baserat på minnesbelastning. Det är upp till utvecklaren att begränsa cachestorleken.
 
Använda IMemoryCache
Warning
Om du använder en delad minnescache från Beroendeinmatning och anropar SetSize, Sizeeller SizeLimit för att begränsa cachestorleken kan det leda till att appen misslyckas. När en storleksgräns har angetts för en cache måste alla poster ange en storlek när de läggs till. Detta kan leda till problem eftersom utvecklare kanske inte har fullständig kontroll över vad som använder den delade cachen.
När du använder SetSize, Sizeeller SizeLimit för att begränsa cacheminnet skapar du en cache-singleton för cachelagring. Mer information och ett exempel finns i Använda SetSize, Size och SizeLimit för att begränsa cachestorleken.
En delad cache delas av andra ramverk eller bibliotek.
Minnescache är en tjänst som refereras från en app med beroendeinjektion. Begär instansen IMemoryCache i konstruktorn:
public class HomeController : Controller
{
    private IMemoryCache _cache;
    public HomeController(IMemoryCache memoryCache)
    {
        _cache = memoryCache;
    }
Följande kod används TryGetValue för att kontrollera om en tid finns i cacheminnet. Om en tid inte finns i cacheminnet skapas en ny post som läggs till i cacheminnet med Set. Klassen CacheKeys är en del av nedladdningsexemplet.
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);
}
Aktuell tid och cachelagrad tid visas:
@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>
Följande kod använder Set-tilläggsmetoden för att cachelagra data för en relativ tidsperiod utan att skapa MemoryCacheEntryOptions-objektet.
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);
}
Det cachelagrade värdet DateTime kvarstår i cacheminnet medan det finns förfrågningar inom tidsgränsen.
Följande kod använder GetOrCreate och GetOrCreateAsync för att cachelagra 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);
}
Följande kod anropar Get för att hämta den cachelagrade tiden:
public IActionResult CacheGet()
{
    var cacheEntry = _cache.Get<DateTime?>(CacheKeys.Entry);
    return View("Cache", cacheEntry);
}
Följande kod hämtar eller skapar ett cachelagrat objekt med absolut förfallotid:
public IActionResult CacheGetOrCreateAbs()
{
    var cacheEntry = _cache.GetOrCreate(CacheKeys.Entry, entry =>
    {
        entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(10);
        return DateTime.Now;
    });
    return View("Cache", cacheEntry);
}
En cachelagrad objektuppsättning med endast en glidande förfallotid riskerar att aldrig upphöra att gälla. Om det cachelagrade objektet används upprepade gånger inom det glidande förfallointervallet upphör objektet aldrig att gälla. Kombinera en glidande förfallotid med en absolut förfallotid för att garantera att objektet upphör att gälla. Den absoluta förfallotiden anger en övre gräns för hur länge objektet kan cachelagras samtidigt som objektet kan upphöra att gälla tidigare om det inte begärs inom det glidande förfallointervallet. Om antingen det glidande förfallointervallet eller den absoluta förfallotiden passerar avlägsnas objektet från cachen.
Följande kod hämtar eller skapar ett cachelagrat objekt med både glidande och absolut förfallotid:
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);
}
Koden ovan garanterar att data inte cachelagras längre än den absoluta tiden.
GetOrCreate, GetOrCreateAsync, och Get är tilläggsmetoder i CacheExtensions klassen. Dessa metoder utökar kapaciteten hos IMemoryCache.
MemoryCacheEntryOptions
Följande exempel:
- Anger en glidande förfallotid. Begäranden som kommer åt det här cachelagrade objektet återställer den glidande förfalloklockan.
- Anger cacheprioriteten till CacheItemPriority.NeverRemove.
- Sätter en PostEvictionDelegate som ska anropas när elementet har tagits bort från cacheminnet. Återanropet körs på en annan tråd än den kod som tar bort objektet från cacheminnet.
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);
}
Använd SetSize, Size och SizeLimit för att begränsa cachestorleken
En MemoryCache instans kan också ange och framtvinga en storleksgräns. Cachestorleksgränsen har ingen definierad måttenhet eftersom cachen inte har någon mekanism för att mäta storleken på poster. Om gränsen för cachestorlek har angetts måste alla poster ange storlek. ASP.NET Core-körningen begränsar inte cachestorleken baserat på minnesbelastning. Det är upp till utvecklaren att begränsa cachestorleken. Den angivna storleken finns i enheter som utvecklaren väljer.
Till exempel:
- Om webbappen främst cachelagrade strängar, kunde storleken på varje cachepost vara stränglängden.
- Appen kan ange storleken på alla poster som 1 och storleksgränsen är antalet poster.
Om SizeLimit inte har angetts växer cachen utan bindning. ASP.NET Core-körningen trimmar inte cacheminnet när systemminnet är lågt. Appar måste utformas för att:
Följande kod skapar en enhetslös fast storlek MemoryCache som kan nås genom beroendeinmatning:
// using Microsoft.Extensions.Caching.Memory;
public class MyMemoryCache 
{
    public MemoryCache Cache { get; private set; }
    public MyMemoryCache()
    {
        Cache = new MemoryCache(new MemoryCacheOptions
        {
            SizeLimit = 1024
        });
    }
}
              SizeLimit har inte enheter. Cachelagrade poster måste ange storlek i de enheter som de anser lämpligast om gränsen för cachestorlek har angetts. Alla användare av en cacheinstans bör använda samma enhetssystem. En post cachelagras inte om summan av de cachelagrade poststorlekarna överskrider det värde som anges av SizeLimit. Om ingen cachestorleksgräns har angetts ignoreras cachestorleken som angetts för posten.
Följande kod registrerar MyMemoryCache med containern för beroendeinjektion.
public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
    services.AddSingleton<MyMemoryCache>();
}
              MyMemoryCache skapas som en oberoende minnescache för komponenter som är medvetna om den här storleksbegränsade cachen och vet hur du ställer in cachepoststorleken på rätt sätt.
Följande kod använder 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");
    }
}
Storleken på cacheposten kan anges av Size eller tilläggsmetoderna SetSize :
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 försöker ta bort den angivna procentandelen av cacheminnet i följande ordning:
- Alla objekt som har upphört att gälla.
- Objekt efter prioritet. Objekt med lägst prioritet tas bort först.
- Minst nyligen använda objekt.
- Objekt med den tidigaste absoluta förfallotiden.
- Objekt med den tidigaste glidande förfallotiden.
Fästa objekt med prioritet NeverRemove tas aldrig bort. Följande kod tar bort ett cacheobjekt och anropar Compact:
_cache.Remove(MyKey);
// Remove 33% of cached items.
_cache.Compact(.33);   
cache_size = _cache.Count;
Mer information finns i Den kompakta källan på GitHub.
Cacheberoenden
Följande exempel visar hur en cachepost löper ut om ett beroende objekt upphör att gälla. Ett CancellationChangeToken läggs till i det cachelagrade objektet. När Cancel anropas på CancellationTokenSource tas båda cacheposterna bort.
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);
}
Med hjälp av en CancellationTokenSource kan flera cacheposter tas bort som en grupp. 
              using Med mönstret i koden ovan ärver cacheposter som skapats i using blocket utlösare och förfalloinställningar.
Ytterligare kommentarer
- Förfallodatum sker inte i bakgrunden. Det finns ingen timer som aktivt söker igenom cachen efter objekt som har upphört att gälla. Alla aktiviteter i cacheminnet ( - Get,- Set,- Remove) kan utlösa en bakgrundssökning efter objekt som har upphört att gälla. En timer på- CancellationTokenSource(CancelAfter) tar också bort posten och utlöser en genomsökning efter objekt som har upphört att gälla. I följande exempel används CancellationTokenSource(TimeSpan) för den registrerade token. När den här token utlöses tar den bort posten omedelbart och utlöser utdrivningsåteranropen.- 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); }
- När du använder ett återanrop för att fylla i ett cacheobjekt igen: - Flera begäranden kan upptäcka att det cachelagrade nyckelvärdet är tomt eftersom återanropet inte har slutförts.
- Detta kan resultera i flera trådar som repopulerar det cachelagrade objektet.
 
- När en cachepost används för att skapa en annan kopierar det underordnade objektet den överordnade postens förfallotoken och tidsbaserade förfalloinställningar. Det underordnade objektet har inte upphört att gälla genom manuell borttagning eller uppdatering av den överordnade posten. 
- Använd PostEvictionCallbacks för att ange återanrop som ska utlöses när cacheposten har avlägsnats från cachen. I exempelkoden CancellationTokenSource.Dispose() anropas för att frigöra de ohanterade resurser som används av - CancellationTokenSource.- CancellationTokenSourceMen tas inte bort omedelbart eftersom den fortfarande används av cacheposten.- CancellationTokenskickas till- MemoryCacheEntryOptionsför att skapa en cachepost som upphör att gälla efter en viss tid. Så- Disposebör inte anropas förrän cacheposten har tagits bort eller upphört att gälla. Exempelkoden anropar RegisterPostEvictionCallback-metoden för att registrera ett återanrop som körs när cacheposten tas bort, och den frigör- CancellationTokenSourcei det återanropet.
- För de flesta appar - IMemoryCacheär aktiverad. Om du till exempel anropar- AddMvc,- AddControllersWithViews,- AddRazorPages,- AddMvcCore().AddRazorViewEngineoch många andra- Add{Service}metoder i- ConfigureServicesaktiverar .- IMemoryCacheFör appar som inte anropar någon av ovanstående- Add{Service}metoder kan det vara nödvändigt att anropa AddMemoryCache i- ConfigureServices.
Uppdatering av bakgrundscache
Använd en bakgrundstjänst , till exempel IHostedService för att uppdatera cacheminnet. Bakgrundstjänsten kan beräkna om posterna och sedan tilldela dem till cacheminnet endast när de är redo.
Ytterligare resurser
ASP.NET Core