Gyorsítótárazás a .NET-ben
Ebben a cikkben megismerheti a különböző gyorsítótárazási mechanizmusokat. A gyorsítótárazás az adatok közbenső rétegben való tárolásának művelete, amely felgyorsítja a későbbi adatlekéréseket. A gyorsítótárazás elméletileg teljesítményoptimalizálási stratégia és tervezési szempont. A gyorsítótárazás jelentősen javíthatja az alkalmazások teljesítményét azáltal, hogy a ritkán változó (vagy költséges) adatok könnyebben elérhetővé válnak. Ez a cikk bemutatja a gyorsítótárazás két elsődleges típusát, és mindkettőhöz biztosít minta forráskódot:
Fontos
A .NET-ben két MemoryCache
osztály található, az egyik a System.Runtime.Caching
névtérben, a másik a Microsoft.Extensions.Caching
névtérben:
Bár ez a cikk a gyorsítótárazással foglalkozik, nem tartalmazza a System.Runtime.Caching
NuGet-csomagot. Minden hivatkozás MemoryCache
a Microsoft.Extensions.Caching
névtérben található.
Az összes csomag készen áll a Microsoft.Extensions.*
függőséginjektálásra (DI), mind az IMemoryCacheIDistributedCache interfészek használhatók szolgáltatásként.
Memóriában való gyorsítótárazás
Ebben a szakaszban megismerheti a Microsoft.Extensions.Caching.Memory csomagot. A jelenlegi implementáció IMemoryCache egy burkoló a ConcurrentDictionary<TKey,TValue>funkciógazdag API körül. A gyorsítótárban lévő bejegyzéseket a ICacheEntry, és bármely object
. A memórián belüli gyorsítótárazási megoldás kiválóan alkalmas olyan alkalmazásokhoz, amelyek egyetlen kiszolgálón futnak, ahol az összes gyorsítótárazott adat memóriát ad ki az alkalmazás folyamatában.
Tipp.
Többkiszolgálós gyorsítótárazási forgatókönyvek esetén az elosztott gyorsítótárazási módszert érdemes a memóriabeli gyorsítótárazás alternatívaként használni.
Memóriabeli gyorsítótárazási API
A gyorsítótár fogyasztója a csúszás és az abszolút lejárat felett is szabályozhatja a következő műveleteket:
- ICacheEntry.AbsoluteExpiration
- ICacheEntry.AbsoluteExpirationRelativeToNow
- ICacheEntry.SlidingExpiration
A lejárat beállítása miatt a gyorsítótár bejegyzései törlődnek, ha nem férnek hozzá a lejárati idő kiosztott időszakán belül. A felhasználók további lehetőségeket is használhatnak a gyorsítótárbejegyzések szabályozására a MemoryCacheEntryOptions. Mindegyik ICacheEntry párosítva MemoryCacheEntryOptions van, amellyel elérhetővé teszi a lejárati kiürítési funkciót a prioritási beállításokkal IChangeTokenés a ICacheEntry.SizevezérlővelCacheItemPriority. Vegye figyelembe a következő bővítménymetelyeket:
- MemoryCacheEntryExtensions.AddExpirationToken
- MemoryCacheEntryExtensions.RegisterPostEvictionCallback
- MemoryCacheEntryExtensions.SetSize
- MemoryCacheEntryExtensions.SetPriority
Példa a memóriabeli gyorsítótárra
Az alapértelmezett IMemoryCache implementáció használatához hívja meg a AddMemoryCache bővítménymetódust, hogy regisztrálja az összes szükséges szolgáltatást a DI-ben. A következő kódmintában az általános gazdagépet használják a DI-funkciók elérhetővé fogadására:
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddMemoryCache();
using IHost host = builder.Build();
A .NET-alapú számítási feladattól függően előfordulhat, hogy másként éri el azokat, például konstruktorinjektálást IMemoryCache
. Ebben a példában a példányt IServiceProvider
használja, és hívja meg az host
általános GetRequiredService<T>(IServiceProvider) bővítménymetódust:
IMemoryCache cache =
host.Services.GetRequiredService<IMemoryCache>();
A memóriabeli gyorsítótárazási szolgáltatások regisztrálva és a DI-n keresztül oldva készen állnak a gyorsítótárazásra. Ez a minta az "A" betűvel a Z betűn keresztül halad végig. A record AlphabetLetter
típus tartalmazza a levélre mutató hivatkozást, és létrehoz egy üzenetet.
file record AlphabetLetter(char Letter)
{
internal string Message =>
$"The '{Letter}' character is the {Letter - 64} letter in the English alphabet.";
}
Tipp.
A file
hozzáférési módosító a típuson AlphabetLetter
van használva, mivel az a Program.cs fájlon belül van definiálva, és csak azokból érhető el. További információ: fájl (C# referencia). A teljes forráskód megtekintéséhez tekintse meg a Program.cs szakaszt.
A minta tartalmaz egy segédfüggvényt, amely az ábécé betűivel halad végig:
static async ValueTask IterateAlphabetAsync(
Func<char, Task> asyncFunc)
{
for (char letter = 'A'; letter <= 'Z'; ++letter)
{
await asyncFunc(letter);
}
Console.WriteLine();
}
Az előző C# kódban:
- Az
Func<char, Task> asyncFunc
egyes iterációkra vár, és átadja az aktuálisatletter
. - Az összes betű feldolgozása után a rendszer egy üres sort ír a konzolra.
Ha elemeket szeretne hozzáadni a gyorsítótárhoz, hívja meg az Create
egyik , vagy Set
API-t:
var addLettersToCacheTask = IterateAlphabetAsync(letter =>
{
MemoryCacheEntryOptions options = new()
{
AbsoluteExpirationRelativeToNow =
TimeSpan.FromMilliseconds(MillisecondsAbsoluteExpiration)
};
_ = options.RegisterPostEvictionCallback(OnPostEviction);
AlphabetLetter alphabetLetter =
cache.Set(
letter, new AlphabetLetter(letter), options);
Console.WriteLine($"{alphabetLetter.Letter} was cached.");
return Task.Delay(
TimeSpan.FromMilliseconds(MillisecondsDelayAfterAdd));
});
await addLettersToCacheTask;
Az előző C# kódban:
- A változó
addLettersToCacheTask
delegáltjai a következőreIterateAlphabetAsync
várnak: - A
Func<char, Task> asyncFunc
lambdával érvelnek. - A
MemoryCacheEntryOptions
példányosított példány abszolút lejárattal rendelkezik a jelenleg érvényeshez képest. - A rendszer regisztrál egy kilakoltatás utáni visszahívást.
- Az
AlphabetLetter
objektum példányosítva lesz, és át lesz adva Set a következővelletter
együtt: ésoptions
. - A rendszer gyorsítótárazottként írja a levelet a konzolra.
- Végül egy Task.Delay lesz visszaadva.
Az ábécé minden betűje esetében a gyorsítótárbejegyzés lejárattal és a kilakoltatás utáni visszahívással lesz megírva.
A kilakoltatás utáni visszahívás a konzolra kiürített érték részleteit írja le:
static void OnPostEviction(
object key, object? letter, EvictionReason reason, object? state)
{
if (letter is AlphabetLetter alphabetLetter)
{
Console.WriteLine($"{alphabetLetter.Letter} was evicted for {reason}.");
}
};
Most, hogy a gyorsítótár feltöltődött, egy újabb hívásra IterateAlphabetAsync
vár, de ezúttal a következőt fogja hívni IMemoryCache.TryGetValue:
var readLettersFromCacheTask = IterateAlphabetAsync(letter =>
{
if (cache.TryGetValue(letter, out object? value) &&
value is AlphabetLetter alphabetLetter)
{
Console.WriteLine($"{letter} is still in cache. {alphabetLetter.Message}");
}
return Task.CompletedTask;
});
await readLettersFromCacheTask;
Ha a cache
kulcs tartalmazza a letter
kulcsot, és az value
egy, a konzolra írt példány AlphabetLetter
. Ha a letter
kulcs nincs a gyorsítótárban, a kulcs ki lett állítva, és a kilakoltatás utáni visszahívása meg lett hívva.
További bővítménymetelyek
Számos IMemoryCache
kényelmi alapú bővítménymetalógussal rendelkezik, köztük aszinkron GetOrCreateAsync
:
- CacheExtensions.Get
- CacheExtensions.GetOrCreate
- CacheExtensions.GetOrCreateAsync
- CacheExtensions.Set
- CacheExtensions.TryGetValue
Az alkalmazás összeállítása
A teljes mintaalkalmazás-forráskód egy legfelső szintű program, és két NuGet-csomagot igényel:
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddMemoryCache();
using IHost host = builder.Build();
IMemoryCache cache =
host.Services.GetRequiredService<IMemoryCache>();
const int MillisecondsDelayAfterAdd = 50;
const int MillisecondsAbsoluteExpiration = 750;
static void OnPostEviction(
object key, object? letter, EvictionReason reason, object? state)
{
if (letter is AlphabetLetter alphabetLetter)
{
Console.WriteLine($"{alphabetLetter.Letter} was evicted for {reason}.");
}
};
static async ValueTask IterateAlphabetAsync(
Func<char, Task> asyncFunc)
{
for (char letter = 'A'; letter <= 'Z'; ++letter)
{
await asyncFunc(letter);
}
Console.WriteLine();
}
var addLettersToCacheTask = IterateAlphabetAsync(letter =>
{
MemoryCacheEntryOptions options = new()
{
AbsoluteExpirationRelativeToNow =
TimeSpan.FromMilliseconds(MillisecondsAbsoluteExpiration)
};
_ = options.RegisterPostEvictionCallback(OnPostEviction);
AlphabetLetter alphabetLetter =
cache.Set(
letter, new AlphabetLetter(letter), options);
Console.WriteLine($"{alphabetLetter.Letter} was cached.");
return Task.Delay(
TimeSpan.FromMilliseconds(MillisecondsDelayAfterAdd));
});
await addLettersToCacheTask;
var readLettersFromCacheTask = IterateAlphabetAsync(letter =>
{
if (cache.TryGetValue(letter, out object? value) &&
value is AlphabetLetter alphabetLetter)
{
Console.WriteLine($"{letter} is still in cache. {alphabetLetter.Message}");
}
return Task.CompletedTask;
});
await readLettersFromCacheTask;
await host.RunAsync();
file record AlphabetLetter(char Letter)
{
internal string Message =>
$"The '{Letter}' character is the {Letter - 64} letter in the English alphabet.";
}
Nyugodtan módosíthatja az MillisecondsDelayAfterAdd
értékeket, MillisecondsAbsoluteExpiration
hogy megfigyelje a viselkedés változásait a gyorsítótárazott bejegyzések lejáratához és kiürítéséhez. Az alábbi mintakimenet a kód futtatásából származik. A .NET-események nem determinisztikus jellege miatt a kimenet eltérő lehet.
A was cached.
B was cached.
C was cached.
D was cached.
E was cached.
F was cached.
G was cached.
H was cached.
I was cached.
J was cached.
K was cached.
L was cached.
M was cached.
N was cached.
O was cached.
P was cached.
Q was cached.
R was cached.
S was cached.
T was cached.
U was cached.
V was cached.
W was cached.
X was cached.
Y was cached.
Z was cached.
A was evicted for Expired.
C was evicted for Expired.
B was evicted for Expired.
E was evicted for Expired.
D was evicted for Expired.
F was evicted for Expired.
H was evicted for Expired.
K was evicted for Expired.
L was evicted for Expired.
J was evicted for Expired.
G was evicted for Expired.
M was evicted for Expired.
N was evicted for Expired.
I was evicted for Expired.
P was evicted for Expired.
R was evicted for Expired.
O was evicted for Expired.
Q was evicted for Expired.
S is still in cache. The 'S' character is the 19 letter in the English alphabet.
T is still in cache. The 'T' character is the 20 letter in the English alphabet.
U is still in cache. The 'U' character is the 21 letter in the English alphabet.
V is still in cache. The 'V' character is the 22 letter in the English alphabet.
W is still in cache. The 'W' character is the 23 letter in the English alphabet.
X is still in cache. The 'X' character is the 24 letter in the English alphabet.
Y is still in cache. The 'Y' character is the 25 letter in the English alphabet.
Z is still in cache. The 'Z' character is the 26 letter in the English alphabet.
Mivel az abszolút lejárat (MemoryCacheEntryOptions.AbsoluteExpirationRelativeToNow) be van állítva, az összes gyorsítótárazott elem végül törlődik.
Feldolgozói szolgáltatás gyorsítótárazása
Az adatok gyorsítótárazásának egyik gyakori stratégiája a gyorsítótár frissítése a felhasználó adatszolgáltatásoktól függetlenül. A Worker Service-sablon kiváló példa, mivel a BackgroundService futtatás független (vagy a háttérben) a másik alkalmazáskódtól. Amikor egy alkalmazás elindul, amely a IHostedServicevégrehajtást üzemelteti, a megfelelő implementáció (ebben az esetben a BackgroundService
"feldolgozó") ugyanabban a folyamatban fog futni. Ezeket a üzemeltetett szolgáltatásokat a bővítménymetóduson keresztül AddHostedService<THostedService>(IServiceCollection) regisztráljuk a DI-ben önállóan. Más szolgáltatások bármilyen szolgáltatási élettartammal regisztrálhatók a DI-ben.
Fontos
A szolgáltatás élettartamát nagyon fontos megérteni. Amikor meghívja AddMemoryCache az összes memóriabeli gyorsítótárazási szolgáltatás regisztrálását, a szolgáltatások egyszeriként lesznek regisztrálva.
Fotószolgáltatás forgatókönyve
Tegyük fel, hogy olyan fotószolgáltatást fejleszt, amely a HTTP-n keresztül elérhető külső API-ra támaszkodik. Ezek a fényképadatok nem változnak túl gyakran, de sok van belőle. Minden fényképet egy egyszerű record
:
namespace CachingExamples.Memory;
public readonly record struct Photo(
int AlbumId,
int Id,
string Title,
string Url,
string ThumbnailUrl);
Az alábbi példában számos szolgáltatás regisztrálva lesz a DI-ben. Minden szolgáltatásnak egyetlen felelőssége van.
using CachingExamples.Memory;
HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
builder.Services.AddMemoryCache();
builder.Services.AddHttpClient<CacheWorker>();
builder.Services.AddHostedService<CacheWorker>();
builder.Services.AddScoped<PhotoService>();
builder.Services.AddSingleton(typeof(CacheSignal<>));
using IHost host = builder.Build();
await host.StartAsync();
Az előző C# kódban:
- Az általános gazdagép alapértelmezés szerint jön létre.
- A memóriabeli gyorsítótárazási szolgáltatások regisztrálva vannak a AddMemoryCache.
- A rendszer regisztrál egy
HttpClient
példányt aCacheWorker
következő osztályhoz AddHttpClient<TClient>(IServiceCollection): . - Az
CacheWorker
osztály regisztrálva van a következővel AddHostedService<THostedService>(IServiceCollection): . - Az
PhotoService
osztály regisztrálva van a következővel AddScoped<TService>(IServiceCollection): . - Az
CacheSignal<T>
osztály regisztrálva van a következővel AddSingleton: . - A
host
példány a szerkesztőből indul ki, és aszinkron módon indult el.
A PhotoService
megadott feltételeknek (vagy filter
):
using Microsoft.Extensions.Caching.Memory;
namespace CachingExamples.Memory;
public sealed class PhotoService(
IMemoryCache cache,
CacheSignal<Photo> cacheSignal,
ILogger<PhotoService> logger)
{
public async IAsyncEnumerable<Photo> GetPhotosAsync(Func<Photo, bool>? filter = default)
{
try
{
await cacheSignal.WaitAsync();
Photo[] photos =
(await cache.GetOrCreateAsync(
"Photos", _ =>
{
logger.LogWarning("This should never happen!");
return Task.FromResult(Array.Empty<Photo>());
}))!;
// If no filter is provided, use a pass-thru.
filter ??= _ => true;
foreach (Photo photo in photos)
{
if (!default(Photo).Equals(photo) && filter(photo))
{
yield return photo;
}
}
}
finally
{
cacheSignal.Release();
}
}
}
Az előző C# kódban:
- A konstruktorhoz egy
IMemoryCache
,CacheSignal<Photo>
ésILogger
. - A
GetPhotosAsync
módszer:- Definiál egy paramétert
Func<Photo, bool> filter
, és visszaad egyIAsyncEnumerable<Photo>
. - Hívások és várakozás a
_cacheSignal.WaitAsync()
kiadásra, ez biztosítja, hogy a gyorsítótár a gyorsítótár elérése előtt fel legyen töltve. - Hívások
_cache.GetOrCreateAsync()
, aszinkron módon leküldi az összes fényképet a gyorsítótárba. - Az
factory
argumentum naplóz egy figyelmeztetést, és egy üres fényképtömböt ad vissza – ez soha nem fordulhat elő. - A gyorsítótárban lévő összes fénykép iterated, filtered és materialized with
yield return
. - Végül a gyorsítótár jelét alaphelyzetbe állítja.
- Definiál egy paramétert
A szolgáltatás felhasználói szabadon felhívják GetPhotosAsync
a metódust, és ennek megfelelően kezelik a fényképeket. Nem HttpClient
szükséges, mivel a gyorsítótár tartalmazza a fényképeket.
Az aszinkron jel egy beágyazott SemaphoreSlim példányon alapul, egy általános típusú korlátozott egytonnán belül. A CacheSignal<T>
következő példányra támaszkodik SemaphoreSlim
:
namespace CachingExamples.Memory;
public sealed class CacheSignal<T>
{
private readonly SemaphoreSlim _semaphore = new(1, 1);
/// <summary>
/// Exposes a <see cref="Task"/> that represents the asynchronous wait operation.
/// When signaled (consumer calls <see cref="Release"/>), the
/// <see cref="Task.Status"/> is set as <see cref="TaskStatus.RanToCompletion"/>.
/// </summary>
public Task WaitAsync() => _semaphore.WaitAsync();
/// <summary>
/// Exposes the ability to signal the release of the <see cref="WaitAsync"/>'s operation.
/// Callers who were waiting, will be able to continue.
/// </summary>
public void Release() => _semaphore.Release();
}
Az előző C#-kódban a dekorátorminta a SemaphoreSlim
. Mivel a CacheSignal<T>
rendszer egyszeriként van regisztrálva, a szolgáltatás minden élettartama alatt használható bármilyen általános típussal – ebben az esetben a Photo
. Feladata a gyorsítótár vetésének jelzése.
A CacheWorker
következő alosztálya BackgroundService:
using System.Net.Http.Json;
using Microsoft.Extensions.Caching.Memory;
namespace CachingExamples.Memory;
public sealed class CacheWorker(
ILogger<CacheWorker> logger,
HttpClient httpClient,
CacheSignal<Photo> cacheSignal,
IMemoryCache cache) : BackgroundService
{
private readonly TimeSpan _updateInterval = TimeSpan.FromHours(3);
private bool _isCacheInitialized = false;
private const string Url = "https://jsonplaceholder.typicode.com/photos";
public override async Task StartAsync(CancellationToken cancellationToken)
{
await cacheSignal.WaitAsync();
await base.StartAsync(cancellationToken);
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
logger.LogInformation("Updating cache.");
try
{
Photo[]? photos =
await httpClient.GetFromJsonAsync<Photo[]>(
Url, stoppingToken);
if (photos is { Length: > 0 })
{
cache.Set("Photos", photos);
logger.LogInformation(
"Cache updated with {Count:#,#} photos.", photos.Length);
}
else
{
logger.LogWarning(
"Unable to fetch photos to update cache.");
}
}
finally
{
if (!_isCacheInitialized)
{
cacheSignal.Release();
_isCacheInitialized = true;
}
}
try
{
logger.LogInformation(
"Will attempt to update the cache in {Hours} hours from now.",
_updateInterval.Hours);
await Task.Delay(_updateInterval, stoppingToken);
}
catch (OperationCanceledException)
{
logger.LogWarning("Cancellation acknowledged: shutting down.");
break;
}
}
}
}
Az előző C# kódban:
- A konstruktorhoz egy
ILogger
,HttpClient
ésIMemoryCache
. - A
_updateInterval
beállítás három órán keresztül van definiálva. - A
ExecuteAsync
módszer:- Hurkok az alkalmazás futtatása közben.
- HTTP-kérést készít,
"https://jsonplaceholder.typicode.com/photos"
és objektumtömbként leképeziPhoto
a választ. - A fényképek tömbje a
IMemoryCache
kulcs alá"Photos"
kerül. - A
_cacheSignal.Release()
hívás, felszabadítja a fogyasztók, akik vártak a jel. - A hívásra Task.Delay a frissítési időköz miatt várni kell.
- Három óra késleltetés után a gyorsítótár ismét frissül.
Az ugyanabban a folyamatban lévő felhasználók kérhetik a IMemoryCache
fényképeket, de a gyorsítótár frissítéséért a CacheWorker
felelős.
Elosztott gyorsítótárazás
Bizonyos esetekben elosztott gyorsítótárra van szükség – ez több alkalmazáskiszolgáló esetében is így van. Az elosztott gyorsítótárak a memóriabeli gyorsítótárazási módszernél nagyobb mértékű felskálázást támogatnak. Az elosztott gyorsítótár használata kiosztja a gyorsítótár memóriáját egy külső folyamatba, de extra hálózati I/O-t igényel, és egy kicsit nagyobb késést eredményez (még akkor is, ha névleges).
Az elosztott gyorsítótárazási absztrakciók a Microsoft.Extensions.Caching.Memory
NuGet-csomag részét képezik, és még egy AddDistributedMemoryCache
bővítménymetódus is létezik.
Figyelemfelhívás
Ez AddDistributedMemoryCache csak fejlesztési és/vagy tesztelési forgatókönyvekben használható, és nem életképes éles megvalósítás.
Vegye figyelembe az alábbi csomagok bármelyik elérhető implementációját IDistributedCache
:
Microsoft.Extensions.Caching.SqlServer
Microsoft.Extensions.Caching.StackExchangeRedis
NCache.Microsoft.Extensions.Caching.OpenSource
Elosztott gyorsítótárazási API
Az elosztott gyorsítótárazási API-k valamivel primitívebbek, mint a memórián belüli gyorsítótárazási API-k. A kulcs-érték párok egy kicsit alaposabbak. A memóriabeli gyorsítótárazási kulcsok egy object
, míg az elosztott kulcsok egy string
. A memórián belüli gyorsítótárazás esetén az érték bármilyen erős típusú általános lehet, míg az elosztott gyorsítótárazási értékek megmaradnak byte[]
. Ez nem azt jelzi, hogy a különböző implementációk nem teszik közzé az erősen gépelt általános értékeket, de ez a megvalósítás részletei.
Értékek létrehozása
Ha értékeket szeretne létrehozni az elosztott gyorsítótárban, hívja meg a beállított API-k egyikét:
AlphabetLetter
A memóriabeli gyorsítótár példájából származó rekord használatával szerializálhatja az objektumot JSON-ra, majd kódolhatja a string
következőkéntbyte[]
:
DistributedCacheEntryOptions options = new()
{
AbsoluteExpirationRelativeToNow =
TimeSpan.FromMilliseconds(MillisecondsAbsoluteExpiration)
};
AlphabetLetter alphabetLetter = new(letter);
string json = JsonSerializer.Serialize(alphabetLetter);
byte[] bytes = Encoding.UTF8.GetBytes(json);
await cache.SetAsync(letter.ToString(), bytes, options);
A memóriabeli gyorsítótárazáshoz hasonlóan a gyorsítótárbejegyzések is segíthetnek a gyorsítótárban való létezésük finomhangolásában – ebben az esetben a DistributedCacheEntryOptions.
Bővítménymetelyek létrehozása
Számos kényelmi alapú bővítménymetódus létezik az értékek létrehozásához, amelyek segítenek elkerülni az objektumok ábrázolásának kódolásátstring
:byte[]
Értékek olvasása
Ha az elosztott gyorsítótárból szeretne értékeket olvasni, hívja meg a get API-k egyikét:
AlphabetLetter? alphabetLetter = null;
byte[]? bytes = await cache.GetAsync(letter.ToString());
if (bytes is { Length: > 0 })
{
string json = Encoding.UTF8.GetString(bytes);
alphabetLetter = JsonSerializer.Deserialize<AlphabetLetter>(json);
}
Ha a gyorsítótár-bejegyzést kiolvassa a gyorsítótárból, lekérheti az UTF8 kódolású string
ábrázolást a byte[]
A bővítmények olvasási módszerei
Az értékek olvasásához számos kényelmi alapú bővítménymetódus létezik, amelyek segítenek elkerülni az objektumok ábrázolására való dekódolást byte[]
string
:
Értékek frissítése
Az elosztott gyorsítótár értékeit nem lehet egyetlen API-hívással frissíteni, ehelyett az értékek a frissítési API-k egyikével alaphelyzetbe állíthatják a csúszó lejáratukat:
Ha a tényleges értéket frissíteni kell, törölnie kell az értéket, majd újra hozzá kell adnia.
Értékek törlése
Az elosztott gyorsítótár értékeinek törléséhez hívja meg az egyik eltávolítási API-t:
Tipp.
Bár a fent említett API-k szinkron verziói léteznek, vegye figyelembe, hogy az elosztott gyorsítótárak implementációi a hálózati I/O-ra támaszkodnak. Ezért gyakrabban érdemes használni az aszinkron API-kat.