Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Rick Anderson, John Luo és Steve Smith
A gyorsítótárazás jelentősen javíthatja az alkalmazások teljesítményét és méretezhetőségét a tartalom létrehozásához szükséges munka csökkentésével. A gyorsítótárazás akkor működik a legjobban, ha az adatok ritkán változnak és költséges a létrehozásuk. Az adatok másolatát készíti el a gyorsítótárazás, ami sokkal gyorsabban visszaadható, mint az eredeti forrásból. Az alkalmazásokat úgy kell írni és tesztelni, hogy soha ne függjenek a gyorsítótárazott adatoktól.
ASP.NET Core számos különböző gyorsítótárat támogat. A legegyszerűbb gyorsítótár a IMemoryCache.
IMemoryCache a webkiszolgáló memóriájában tárolt gyorsítótárat jelöli. A szerverfarmon (több kiszolgálón) futó alkalmazásoknak biztosítaniuk kell, hogy a munkamenetek ragadósak legyenek a memóriában történő gyorsítótárazás során. A ragadós munkamenetek biztosítják, hogy az ügyféltől érkező kérések mind ugyanarra a kiszolgálóra menjenek. Az Azure Web Apps például az Application Request Routing (ARR) használatával irányítja az összes kérést ugyanarra a kiszolgálóra.
A webfarmok nem ragadós munkamenetei elosztott gyorsítótárat igényelnek a gyorsítótár konzisztenciaproblémáinak elkerülése érdekében. Egyes alkalmazások esetében az elosztott gyorsítótárak nagyobb mértékű felskálázást támogatnak, mint a memóriabeli gyorsítótárak. Elosztott gyorsítótár használata kiosztja a gyorsítótár memóriáját egy külső folyamatba.
A memóriabeli gyorsítótár bármilyen objektumot tárolhat. Az elosztott gyorsítótár-illesztő korlátozva a byte[]-re. A memóriabeli és az elosztott gyorsítótár kulcs-érték párként tárolja a gyorsítótár elemeit.
System.Runtime.Caching/MemoryCache
System.Runtime.Caching / MemoryCache (NuGet-csomag) a következőkkel használható:
- .NET Standard 2.0 vagy újabb.
- Minden .NET-implementáció , amely a .NET Standard 2.0-s vagy újabb verzióját célozza. Például ASP.NET Core 3.1-et vagy újabb verziót.
- .NET-keretrendszer 4.5-ös vagy újabb verziója.
A Microsoft.Extensions.Caching.Memory/IMemoryCache (ebben a cikkben ismertetett) használata ajánlottSystem.Runtime.Caching/MemoryCache, mert jobban integrálható ASP.NET Core-ba. Például IMemoryCache natív módon működik ASP.NET Core függőséginjektálással.
Kompatibilitási hídként használható System.Runtime.Caching/MemoryCache a kód ASP.NET 4.x-ből ASP.NET Core-ba történő portolásához.
Gyorsítótárra vonatkozó irányelvek
- A kódnak mindig rendelkeznie kell egy tartalék lehetőséggel az adatok lehívásához, és nem szabad attól függnie, hogy elérhető-e egy gyorsítótárazott érték.
- A gyorsítótár kevés erőforrást, memóriát használ. A gyorsítótár növekedésének korlátozása:
- Ne szúrjon be külső bemenetet a gyorsítótárba. Például nem ajánlott tetszőleges, felhasználó által megadott bemenetet gyorsítótárkulcsként használni, mivel a bemenet kiszámíthatatlan mennyiségű memóriát használhat fel.
- A gyorsítótár növekedésének korlátozásához használjon lejáratokat.
- A Gyorsítótár méretének korlátozásához használja a SetSize, a Size és a SizeLimit parancsot. A ASP.NET Core-futtatókörnyezet nem korlátozza a gyorsítótár méretét a memóriaterhelés alapján. A gyorsítótár méretének korlátozása a fejlesztőn múlik.
Az IMemoryCache használata
Warning
Ha megosztott memória-gyorsítótárat használ a függőséginjektálásból, és hívja a(z) SetSize, Size vagy SizeLimit funkciókat a gyorsítótár méretének korlátozására, az alkalmazás meghibásodhat. Ha a gyorsítótárban méretkorlát van beállítva, a hozzáadáskor minden bejegyzésnek meg kell adnia a méretet. Ez problémákhoz vezethet, mivel előfordulhat, hogy a fejlesztők nem tudják teljes mértékben szabályozni, hogy mi használja a megosztott gyorsítótárat.
Amikor a SetSize, Size vagy SizeLimit elemet használja a gyorsítótár korlátozására, hozzon létre egy gyorsítótár-egyton objektumot a gyorsítótárazáshoz. További információ és példa: A SetSize, a Size és a SizeLimit használata a gyorsítótár méretének korlátozásához.
A megosztott gyorsítótárat más keretrendszerek vagy tárak osztják meg.
A memóriabeli gyorsítótárazás egy olyan szolgáltatás, amelyre egy függőséginjektálást használó alkalmazásból hivatkoznak. Kérje le a példányt IMemoryCache a konstruktorban:
public class IndexModel : PageModel
{
private readonly IMemoryCache _memoryCache;
public IndexModel(IMemoryCache memoryCache) =>
_memoryCache = memoryCache;
// ...
Az alábbi kód TryGetValue használja annak ellenőrzésére, hogy van-e az idő a gyorsítótárban. Ha egy időpont nincs gyorsítótárazva, a rendszer létrehoz egy új bejegyzést, és hozzáadja a gyorsítótárhoz a következővel 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;
}
Az előző kódban a gyorsítótár-bejegyzés három másodperces csúszó lejárattal van konfigurálva. Ha a gyorsítótár-bejegyzés három másodpercnél hosszabb ideig nem érhető el, a gyorsítótárból kizárja. A gyorsítótár-bejegyzés minden elérésekor további 3 másodpercig a gyorsítótárban marad. Az CacheKeys osztály a letöltési minta része.
Az aktuális és a gyorsítótárazott idő jelenik meg:
<ul>
<li>Current Time: @Model.CurrentDateTime</li>
<li>Cached Time: @Model.CacheCurrentDateTime</li>
</ul>
A következő kód a Set bővítménymetódus használatával gyorsítótárazza az adatokat egy relatív időtartamra e nélkül MemoryCacheEntryOptions.
_memoryCache.Set(CacheKeys.Entry, DateTime.Now, TimeSpan.FromDays(1));
Az előző kódban a gyorsítótár-bejegyzés egy nap relatív lejáratával van konfigurálva. A gyorsítótárbejegyzést egy nap múlva kiüríti a gyorsítótárból, még akkor is, ha az ezen időkorláton belül elérhető.
Az alábbi kód GetOrCreate és GetOrCreateAsync használatával gyorsítótárba helyezi az adatokat.
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);
});
// ...
}
Az alábbi kódhívások Get a gyorsítótárazott idő beolvasásához:
var cacheEntry = _memoryCache.Get<DateTime?>(CacheKeys.Entry);
A következő kód egy gyorsítótárazott elemet kap vagy hoz létre abszolút lejárati idővel.
var cachedValue = _memoryCache.GetOrCreate(
CacheKeys.Entry,
cacheEntry =>
{
cacheEntry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(20);
return DateTime.Now;
});
A csak csúszó lejárattal rendelkező gyorsítótárazott elemek esetében fennáll a veszélye annak, hogy soha nem jár le. Ha a gyorsítótárazott elemet a csúszó lejárati időszakon belül ismételten elérik, az elem soha nem jár le. A csúszó lejárat és az abszolút lejárat kombinálásával garantálható az elem lejárata. Az abszolút lejárat egyrészt azt határozza meg, hogy az elem mennyi ideig tárolható, másrészt lehetővé teszi az elem korábban lejárjon, ha nem kérik a csúszó lejárati időszakon belül. Ha a csúszó lejárati időköz vagy az abszolút lejárati idő lejárt, a rendszer kizárja az elemet a gyorsítótárból.
Az alábbi kód lekér egy gyorsítótárba helyezett elemet, vagy létrehoz egyet csúszó és abszolút lejárattal.
var cachedValue = _memoryCache.GetOrCreate(
CacheKeys.CallbackEntry,
cacheEntry =>
{
cacheEntry.SlidingExpiration = TimeSpan.FromSeconds(3);
cacheEntry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(20);
return DateTime.Now;
});
Az előző kód garantálja, hogy az adatok nem lesznek gyorsítótárazva az abszolút időnél hosszabb ideig.
GetOrCreate, GetOrCreateAsyncés Get az osztályban a CacheExtensions bővítménymetelyek. Ezek a metódusok kibővítik a IMemoryCache képességeit.
MemoryCacheEntryOptions
A következő példa:
- A gyorsítótár prioritását a következőre CacheItemPriority.NeverRemoveállítja: .
- Beállít egy PostEvictionDelegate-t, amelyet a bejegyzés gyorsítótárból való eltávolítása után hívnak meg. A visszahívás a kódtól eltérő szálon fut, amely eltávolítja az elemet a gyorsítótárból.
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}.");
}
A SetSize, a Size és a SizeLimit használata a gyorsítótár méretének korlátozásához
A MemoryCache példány opcionálisan megadhatja és kikényszerítheti a méretkorlátot. A gyorsítótár méretkorlátja nem rendelkezik meghatározott mértékegységekkel, mert a gyorsítótár nem rendelkezik a bejegyzések méretének mérésére szolgáló mechanizmussal. Ha a gyorsítótár méretkorlátja be van állítva, minden bejegyzésnek meg kell adnia a méretet. A ASP.NET Core-futtatókörnyezet nem korlátozza a gyorsítótár méretét a memóriaterhelés alapján. A gyorsítótár méretének korlátozása a fejlesztőn múlik. A megadott méret a fejlesztő által választott egységekben van megadva.
Például:
- Ha a webalkalmazás elsősorban karakterláncok gyorsítótárazásával foglalkozik, minden gyorsítótárbejegyzés mérete lehet a karakterlánc hossza.
- Az alkalmazás az összes bejegyzés méretét 1-ként határozhatja meg, a méretkorlát pedig a bejegyzések száma.
Ha SizeLimit nincs beállítva, a gyorsítótár kötöttség nélkül növekszik. A ASP.NET Core-futtatókörnyezet nem csökkenti a gyorsítótárat, ha a rendszermemória alacsony. Az alkalmazásokat a következőre kell létrehozni:
- Korlátozza a gyorsítótár növekedését.
- Hívja Compact, vagy Remove, ha a rendelkezésre álló memória korlátozott.
Az alábbi kód egy, MemoryCache elérhető, egység nélküli rögzített méretet hoz létre:
public class MyMemoryCache
{
public MemoryCache Cache { get; } = new MemoryCache(
new MemoryCacheOptions
{
SizeLimit = 1024
});
}
SizeLimit nem rendelkezik egységekkel. A gyorsítótárazott bejegyzéseknek meg kell adniuk a méretet az általuk legmegfelelőbbnek ítélt egységekben, ha a gyorsítótár méretkorlátja be van állítva. A gyorsítótárpéldány minden felhasználójának ugyanazt az egységrendszert kell használnia. A rendszer nem gyorsítótárazza a bejegyzéseket, ha a gyorsítótárazott bejegyzésméretek összege meghaladja a megadott SizeLimitértéket. Ha nincs gyorsítótárméretkorlát beállítva, a rendszer figyelmen kívül hagyja a bejegyzés gyorsítótárméret-beállítását.
A következő kód regisztrálja a(z) MyMemoryCache elemet a függőséginjektáló tárolóban:
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddSingleton<MyMemoryCache>();
MyMemoryCache önálló memória-gyorsítótárként jön létre azon összetevők számára, amelyek tisztában vannak ezzel a mérettel korlátozott gyorsítótárral, és tudják, hogyan kell megfelelően beállítani a gyorsítótár-bejegyzés méretét.
A gyorsítótár-bejegyzés mérete a bővítménymetódus vagy a SetSizeSize tulajdonság használatával állítható be:
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);
}
Az előző kódban a két kiemelt sor ugyanazt az eredményt éri el, mint a gyorsítótár-bejegyzés méretének beállítása.
SetSize a kényelem érdekében van biztosítva, amikor a hívásokat a new MemoryCacheOptions()-ra láncolják.
MemoryCache.Compact
MemoryCache.Compact a gyorsítótár megadott százalékos arányát a következő sorrendben próbálja eltávolítani:
- Minden lejárt tétel.
- Elemek prioritás szerint. A rendszer először a legalacsonyabb prioritású elemeket távolítja el.
- Legrégebben használt objektumok.
- A legkorábbi abszolút lejáratú elemek.
- A legkorábbi eltolható lejáratú elemek.
A prioritással NeverRemove ellátott rögzített elemek soha nem lesznek eltávolítva. Az alábbi kód eltávolít egy gyorsítótár-elemet, és meghívja Compact a gyorsítótárazott bejegyzések 25% eltávolítására:
_myMemoryCache.Cache.Remove(CacheKeys.Entry);
_myMemoryCache.Cache.Compact(.25);
További információt a GitHub Kompakt forrásában talál.
Gyorsítótár-függőségek
Az alábbi minta bemutatja, hogyan lehet lejáratni egy gyorsítótár-bejegyzést, ha egy függő bejegyzés lejár. A CancellationChangeToken hozzáadásra kerül a gyorsítótárazott elemhez. Amikor a Cancel-t meghívják a CancellationTokenSource-en, mindkét gyorsítótár-bejegyzés eltávolításra kerül.
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();
}
CancellationTokenSource használatával több gyorsítótárbejegyzés is eltávolítható csoportként. A fenti kódban található using mintával az ebben a using hatókörben létrehozott gyorsítótárbejegyzések öröklik az eseményindítókat és a lejárati beállításokat.
További megjegyzések
A lejárat nem zajlik a háttérben. Nincs olyan időzítő, amely aktívan átvizsgálja a gyorsítótárat a lejárt elemek után. A gyorsítótárban (
Get, ,TryGetValueSet,Remove) végzett bármely tevékenység elindíthatja a lejárt elemek háttérvizsgálatát. ACancellationTokenSourceidőzítő a CancelAfter rendszeren is eltávolítja a bejegyzést, és elindítja a lejárt elemek vizsgálatát. Az alábbi példa a CancellationTokenSource(TimeSpan) regisztrált tokent használja. Amikor ez a token aktiválódik, azonnal eltávolítja a bejegyzést, és végrehajtja az eltávolítási visszahívásokat.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); }Ha visszahívást használ a gyorsítótárelem újratöltéséhez:
- Több kérés esetén is előfordulhat, hogy a gyorsítótárban lévő kulcs értéke üres, mert a visszahívás még nem fejeződött be.
- Ez azt eredményezheti, hogy több szál is feltölti a gyorsítótárazott elemet.
Amikor egy gyorsítótár-bejegyzést használ egy másik létrehozásához, a gyermek átmásolja a szülőbejegyzés lejárati jogkivonatait és az időalapú lejárati beállításokat. A gyermek nem járt le a szülőbejegyzés manuális eltávolításával vagy frissítésével.
Az PostEvictionCallbacks a visszahívások beállítására használható, amelyek a gyorsítótár-bejegyzés gyorsítótárból való törlése után aktiválódnak.
A legtöbb alkalmazás
IMemoryCacheesetében engedélyezve van. Például aAddMvc,AddControllersWithViews,AddRazorPages,AddMvcCore().AddRazorViewEngineés sok másAdd{Service}metódus hívása aProgram.cs-ben lehetővé teszi aIMemoryCache-t. Az olyan alkalmazások esetében, amelyek nem hívják meg az előző módszerek egyikétAdd{Service}, előfordulhat, hogy be kell hívniAddMemoryCache aProgram.cs-ban.
Háttér gyorsítótár frissítése
Használjon háttérszolgáltatást , például IHostedService frissítse a gyorsítótárat. A háttérszolgáltatás újratervezheti a bejegyzéseket, és csak akkor rendelheti hozzá őket a gyorsítótárhoz, amikor készen vannak.
További erőforrások
- Mintakód megtekintése vagy letöltése (hogyan töltsd le)
- Elosztott gyorsítótárazás az ASP.NET Core-ban
- Változások észlelése változási tokenekkel az ASP.NET Core
- Válasz gyorsítótárazása az ASP.NET Core-ban
- Response Caching Middleware az ASP.NET Core
- Cache Tag Helper az ASP.NET Core MVC
- Elosztott gyorsítótár címke segédprogram az ASP.NET Core-ban
Mintakód megtekintése vagy letöltése (hogyan töltsd le)
Gyorsítótárazási alapismeretek
A gyorsítótárazás jelentősen javíthatja az alkalmazások teljesítményét és méretezhetőségét a tartalom létrehozásához szükséges munka csökkentésével. A gyorsítótárazás akkor működik a legjobban, ha az adatok ritkán változnak és költséges a létrehozásuk. Az adatok másolatát készíti el a gyorsítótárazás, ami sokkal gyorsabban visszaadható, mint az eredeti forrásból. Az alkalmazásokat úgy kell írni és tesztelni, hogy soha ne függjenek a gyorsítótárazott adatoktól.
ASP.NET Core számos különböző gyorsítótárat támogat. A legegyszerűbb gyorsítótár a IMemoryCache.
IMemoryCache a webkiszolgáló memóriájában tárolt gyorsítótárat jelöli. A szerverfarmon (több kiszolgálón) futó alkalmazásoknak biztosítaniuk kell, hogy a munkamenetek ragadósak legyenek a memóriában történő gyorsítótárazás során. A ragadós munkamenetek biztosítják, hogy az ügyfél későbbi kérései mind ugyanarra a kiszolgálóra menjenek. Az Azure Web Apps például az Application Request Routing (ARR) használatával irányítja az összes további kérést ugyanarra a kiszolgálóra.
A webfarmok nem ragadós munkamenetei elosztott gyorsítótárat igényelnek a gyorsítótár konzisztenciaproblémáinak elkerülése érdekében. Egyes alkalmazások esetében az elosztott gyorsítótárak nagyobb mértékű felskálázást támogatnak, mint a memóriabeli gyorsítótárak. Elosztott gyorsítótár használata kiosztja a gyorsítótár memóriáját egy külső folyamatba.
A memóriabeli gyorsítótár bármilyen objektumot tárolhat. Az elosztott gyorsítótár-illesztő korlátozva a byte[]-re. A memóriabeli és az elosztott gyorsítótár kulcs-érték párként tárolja a gyorsítótár elemeit.
System.Runtime.Caching/MemoryCache
System.Runtime.Caching / MemoryCache (NuGet-csomag) a következőkkel használható:
- .NET Standard 2.0 vagy újabb.
- Minden .NET-implementáció , amely a .NET Standard 2.0-s vagy újabb verzióját célozza. Például ASP.NET Core 3.1-et vagy újabb verziót.
- .NET-keretrendszer 4.5-ös vagy újabb verziója.
A Microsoft.Extensions.Caching.Memory/IMemoryCache (ebben a cikkben ismertetett) használata ajánlottSystem.Runtime.Caching/MemoryCache, mert jobban integrálható ASP.NET Core-ba. Például IMemoryCache natív módon működik ASP.NET Core függőséginjektálással.
Kompatibilitási hídként használható System.Runtime.Caching/MemoryCache a kód ASP.NET 4.x-ből ASP.NET Core-ba történő portolásához.
Gyorsítótárra vonatkozó irányelvek
- A kódnak mindig rendelkeznie kell egy tartalék lehetőséggel az adatok lehívásához, és nem szabad attól függnie, hogy elérhető-e egy gyorsítótárazott érték.
- A gyorsítótár kevés erőforrást, memóriát használ. A gyorsítótár növekedésének korlátozása:
- Ne használjon külső bemenetet gyorsítótárkulcsként.
- A gyorsítótár növekedésének korlátozásához használjon lejáratokat.
- A Gyorsítótár méretének korlátozásához használja a SetSize, a Size és a SizeLimit parancsot. A ASP.NET Core-futtatókörnyezet nem korlátozza a gyorsítótár méretét a memóriaterhelés alapján. A gyorsítótár méretének korlátozása a fejlesztőn múlik.
Az IMemoryCache használata
Warning
Ha megosztott memória-gyorsítótárat használ a függőséginjektálásból, és hívja a(z) SetSize, Size vagy SizeLimit funkciókat a gyorsítótár méretének korlátozására, az alkalmazás meghibásodhat. Ha a gyorsítótárban méretkorlát van beállítva, a hozzáadáskor minden bejegyzésnek meg kell adnia a méretet. Ez problémákhoz vezethet, mivel előfordulhat, hogy a fejlesztők nem tudják teljes mértékben szabályozni, hogy mi használja a megosztott gyorsítótárat.
Amikor a SetSize, Size vagy SizeLimit elemet használja a gyorsítótár korlátozására, hozzon létre egy gyorsítótár-egyton objektumot a gyorsítótárazáshoz. További információ és példa: A SetSize, a Size és a SizeLimit használata a gyorsítótár méretének korlátozásához.
A megosztott gyorsítótárat más keretrendszerek vagy tárak osztják meg.
A memóriabeli gyorsítótárazás egy olyan szolgáltatás, amelyre egy függőséginjektálást használó alkalmazásból hivatkoznak. Kérje le a példányt IMemoryCache a konstruktorban:
public class HomeController : Controller
{
private IMemoryCache _cache;
public HomeController(IMemoryCache memoryCache)
{
_cache = memoryCache;
}
Az alábbi kód TryGetValue használja annak ellenőrzésére, hogy van-e az idő a gyorsítótárban. Ha egy időpont nincs gyorsítótárazva, a rendszer létrehoz egy új bejegyzést, és hozzáadja a gyorsítótárhoz a következővel Set: . Az CacheKeys osztály a letöltési minta része.
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);
}
Az aktuális és a gyorsítótárazott idő jelenik meg:
@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 következő kód a Set bővítménymetódussal gyorsítótárazza az adatokat relatív ideig az MemoryCacheEntryOptions objektum létrehozása nélkül:
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);
}
A gyorsítótárazott DateTime érték a gyorsítótárban marad, amíg az időtúllépési időszakon belül kérések vannak.
Az alábbi kód GetOrCreate és GetOrCreateAsync használatával gyorsítótárba helyezi az adatokat.
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);
}
Az alábbi kódhívások Get a gyorsítótárazott idő beolvasásához:
public IActionResult CacheGet()
{
var cacheEntry = _cache.Get<DateTime?>(CacheKeys.Entry);
return View("Cache", cacheEntry);
}
A következő kód egy gyorsítótárazott elemet kap vagy hoz létre abszolút lejárati idővel.
public IActionResult CacheGetOrCreateAbs()
{
var cacheEntry = _cache.GetOrCreate(CacheKeys.Entry, entry =>
{
entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(10);
return DateTime.Now;
});
return View("Cache", cacheEntry);
}
A csak csúszó lejárattal rendelkező gyorsítótárazott elemek esetében fennáll a veszélye annak, hogy soha nem jár le. Ha a gyorsítótárazott elemet a csúszó lejárati időszakon belül ismételten elérik, az elem soha nem jár le. A csúszó lejárat és az abszolút lejárat kombinálásával garantálható az elem lejárata. Az abszolút lejárat egyrészt azt határozza meg, hogy az elem mennyi ideig tárolható, másrészt lehetővé teszi az elem korábban lejárjon, ha nem kérik a csúszó lejárati időszakon belül. Ha a csúszó lejárati időköz vagy az abszolút lejárati idő lejárt, a rendszer kizárja az elemet a gyorsítótárból.
Az alábbi kód lekér egy gyorsítótárba helyezett elemet, vagy létrehoz egyet csúszó és abszolút lejárattal.
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);
}
Az előző kód garantálja, hogy az adatok az abszolút időnél hosszabb ideig nem lesznek gyorsítótárazva.
GetOrCreate, GetOrCreateAsyncés Get az osztályban a CacheExtensions bővítménymetelyek. Ezek a metódusok kibővítik a IMemoryCache képességeit.
MemoryCacheEntryOptions
A következő minta:
- Eltolható lejárati időt állít be. A gyorsítótárazott elemhez hozzáférő kérések visszaállítják a csúszó lejárat idejét.
- A gyorsítótár prioritását a következőre CacheItemPriority.NeverRemoveállítja: .
- Beállít egy PostEvictionDelegate, amelyet a bejegyzés gyorsítótárból történő törlése után hív meg. A visszahívás a kódtól eltérő szálon fut, amely eltávolítja az elemet a gyorsítótárból.
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);
}
A SetSize, a Size és a SizeLimit használata a gyorsítótár méretének korlátozásához
A MemoryCache példány opcionálisan megadhatja és kikényszerítheti a méretkorlátot. A gyorsítótár méretkorlátja nem rendelkezik meghatározott mértékegységekkel, mert a gyorsítótár nem rendelkezik a bejegyzések méretének mérésére szolgáló mechanizmussal. Ha a gyorsítótár méretkorlátja be van állítva, minden bejegyzésnek meg kell adnia a méretet. A ASP.NET Core-futtatókörnyezet nem korlátozza a gyorsítótár méretét a memóriaterhelés alapján. A gyorsítótár méretének korlátozása a fejlesztőn múlik. A megadott méret a fejlesztő által választott egységekben van megadva.
Például:
- Ha a webalkalmazás elsősorban karakterláncok gyorsítótárazásával foglalkozik, minden gyorsítótárbejegyzés mérete lehet a karakterlánc hossza.
- Az alkalmazás az összes bejegyzés méretét 1-ként határozhatja meg, a méretkorlát pedig a bejegyzések száma.
Ha SizeLimit nincs beállítva, a gyorsítótár kötöttség nélkül növekszik. A ASP.NET Core-futtatókörnyezet nem csökkenti a gyorsítótárat, ha a rendszermemória alacsony. Az alkalmazásokat a következőre kell létrehozni:
- Korlátozza a gyorsítótár növekedését.
- Hívás Compact vagy Remove ha a rendelkezésre álló memória korlátozott:
Az alábbi kód egy, MemoryCache elérhető, egység nélküli rögzített méretet hoz létre:
// using Microsoft.Extensions.Caching.Memory;
public class MyMemoryCache
{
public MemoryCache Cache { get; private set; }
public MyMemoryCache()
{
Cache = new MemoryCache(new MemoryCacheOptions
{
SizeLimit = 1024
});
}
}
SizeLimit nem rendelkezik egységekkel. A gyorsítótárazott bejegyzéseknek meg kell adniuk a méretet az általuk legmegfelelőbbnek ítélt egységekben, ha a gyorsítótár méretkorlátja be van állítva. A gyorsítótárpéldány minden felhasználójának ugyanazt az egységrendszert kell használnia. A rendszer nem gyorsítótárazza a bejegyzéseket, ha a gyorsítótárazott bejegyzésméretek összege meghaladja a megadott SizeLimitértéket. Ha nincs megadva a gyorsítótár méretkorlátja, a rendszer figyelmen kívül hagyja a bejegyzés gyorsítótárméret-beállítását.
A következő kód a MyMemoryCache elemet regisztrálja a függőségkezelő konténerben.
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddSingleton<MyMemoryCache>();
}
MyMemoryCache önálló memória-gyorsítótárként jön létre azon összetevők számára, amelyek tisztában vannak ezzel a mérettel korlátozott gyorsítótárral, és tudják, hogyan kell megfelelően beállítani a gyorsítótár-bejegyzés méretét.
A következő kód MyMemoryCachehasznál:
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");
}
}
A gyorsítótár-bejegyzés méretét a Size vagy a SetSize bővítménymetódusokkal lehet beállítani.
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 a gyorsítótár megadott százalékos arányát a következő sorrendben próbálja eltávolítani:
- Minden lejárt tétel.
- Elemek prioritás szerint. A rendszer először a legalacsonyabb prioritású elemeket távolítja el.
- Legrégebben használt objektumok.
- A legkorábbi abszolút lejáratú elemek.
- A legkorábbi eltolható lejáratú elemek.
A prioritással NeverRemove ellátott rögzített elemek soha nem lesznek eltávolítva. A következő kód eltávolít egy gyorsítótár-elemet, és meghívja a következőt Compact:
_cache.Remove(MyKey);
// Remove 33% of cached items.
_cache.Compact(.33);
cache_size = _cache.Count;
További információt a GitHub Kompakt forrásában talál.
Gyorsítótár-függőségek
Az alábbi minta bemutatja, hogyan lehet lejáratni egy gyorsítótár-bejegyzést, ha egy függő bejegyzés lejár. A CancellationChangeToken hozzáadásra kerül a gyorsítótárazott elemhez. Amikor a Cancel hívja meg a CancellationTokenSource-t, mindkét gyorsítótár-bejegyzés kiürül.
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);
}
CancellationTokenSource használatával több gyorsítótárbejegyzés is eltávolítható csoportként.
using A fenti kódban szereplő mintával a blokkban létrehozott gyorsítótárbejegyzések öröklik az eseményindítókat és a using lejárati beállításokat.
További megjegyzések
A lejárat nem zajlik a háttérben. Nincs olyan időzítő, amely aktívan megvizsgálja a gyorsítótárat a lejárt elemek után. A gyorsítótárban (
Get, ,SetRemove) végzett bármely tevékenység elindíthatja a lejárt elemek háttérvizsgálatát. ACancellationTokenSourceidőzítő a CancelAfter rendszeren is eltávolítja a bejegyzést, és elindítja a lejárt elemek vizsgálatát. Az alábbi példa a CancellationTokenSource(TimeSpan) regisztrált tokent használja. Amikor ez a token aktiválódik, azonnal eltávolítja a bejegyzést, és aktiválja az eltávolítási visszahívásokat.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); }Ha visszahívást használ a gyorsítótárelem újratöltéséhez:
- Több kérés esetén is előfordulhat, hogy a gyorsítótárban lévő kulcs értéke üres, mert a visszahívás még nem fejeződött be.
- Ez azt eredményezheti, hogy több szál is feltölti a gyorsítótárazott elemet.
Amikor egy gyorsítótár-bejegyzést használ egy másik létrehozásához, a gyermek átmásolja a szülőbejegyzés lejárati jogkivonatait és az időalapú lejárati beállításokat. A gyermek nem járt le a szülőbejegyzés manuális eltávolításával vagy frissítésével.
Az PostEvictionCallbacks a visszahívások beállítására használható, amelyek a gyorsítótár-bejegyzés gyorsítótárból való törlése után aktiválódnak. A példakódban a CancellationTokenSource.Dispose() van meghívva a
CancellationTokenSourceáltal használt nem felügyelt erőforrások felszabadítására. ACancellationTokenSourceazonban nem kerül azonnal eltávolításra, mert a gyorsítótár-bejegyzés még használja. AzCancellationTokenátadásra kerülMemoryCacheEntryOptionsszámára, hogy létrehozzon egy gyorsítótár-bejegyzést, amely egy bizonyos idő után lejár. ÍgyDisposecsak akkor hívható meg, ha a gyorsítótár-bejegyzést eltávolították vagy lejárt. A példakód meghívja a RegisterPostEvictionCallback metódust, hogy regisztráljon egy visszahívást, amely a gyorsítótár-bejegyzés kiürítésekor fog végrehajtódni, és ebben a visszahívásban felszabadítja aCancellationTokenSource-t.A legtöbb alkalmazás
IMemoryCacheesetében engedélyezve van. Például aAddMvc,AddControllersWithViews,AddRazorPages,AddMvcCore().AddRazorViewEngineés sok másAdd{Service}metódus hívása aConfigureServices-ben lehetővé teszi aIMemoryCache-t. Az olyan alkalmazások esetében, amelyek nem az előzőAdd{Service}módszerek egyikét hívják meg, előfordulhat, hogy szükség lehet a AddMemoryCache behívásáraConfigureServices.
Háttér gyorsítótár frissítése
Használjon háttérszolgáltatást , például IHostedService frissítse a gyorsítótárat. A háttérszolgáltatás újratervezheti a bejegyzéseket, és csak akkor rendelheti hozzá őket a gyorsítótárhoz, amikor készen vannak.