Neu in .NET 7.0 [19]: Statistiken fĂĽr den MemoryCache
Die Klasse zum Repräsentieren des Cache im Arbeitsspeicher bietet in .NET 7.0 einige Funktionen für Statistiken der Nutzung des Zwischenspeichers.
- Dr. Holger Schwichtenberg
Die Klasse MemoryCache
im Namensraum Microsoft.Extensions.Caching.Memory
ist schon recht alt. Im klassischen .NET Framework gibt es sie seit .NET Framework 4.0, im modernen .NET seit .NET Core 2.1. Neu in .NET 7.0 ist die Methode GetCurrentStatistics()
, die ein Objekt des Typs MemoryCacheStatistics
mit vier selbsterklärenden Eigenschaften liefert:
CurrentEntryCount
CurrentEstimatedSize
TotalHits
TotalMisses
Voraussetzung ist, dass man die Statistiken im MemoryCache
aktiviert:
using System.Runtime.Serialization.Formatters.Binary;
using ITVisions;
using Microsoft.Extensions.Caching.Memory;
namespace NET7Console;
internal class FCL_Caching
{
/// <summary>
/// Klasse fĂĽr das Objekt, das in den Cache soll
/// </summary>
[Serializable]
class Developer
{
public long ID { get; set; }
public string? Name { get; set; }
public string? Company { get; set; }
public override string ToString()
{
return $"Developer {Name} entwickelt bei {Company}.";
}
}
/// <summary>
/// Hilfsfunktion: Ermittelt die ungefähre Größe eines
/// beliebigen .NET-Objekts per binärer Serialisierung
/// </summary>
private int GetObjectSize(object TestObject)
{
#pragma warning disable SYSLIB0011
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
byte[] Array;
bf.Serialize(ms, TestObject);
Array = ms.ToArray();
return Array.Length;
#pragma warning restore SYSLIB0011
}
public void MemoryCacheDemo()
{
CUI.H1("MemoryCacheDemo mit .NET 7.0" +
"(C) Dr. Holger Schwichtenberg 2022");
var co = new MemoryCacheOptions();
co.TrackStatistics = true;
co.SizeLimit = 1024; // hier Einheit Bytes
MemoryCache cache = new MemoryCache(co);
CUI.PrintStep("Ein Objekt wird fĂĽr fĂĽnf Sekunden" +
"in den Zwischenspeicher gelegt");
var d = new Developer() {
ID = 123,
Name = "Dr. Holger Schwichtenberg",
Company = "MAXIMAGO GmbH" };
Console.WriteLine(d);
var g = GetObjectSize(d);
Console.WriteLine("Größe des Objekts: " + g);
var ceo = new MemoryCacheEntryOptions();
ceo.Size = g;
ceo.AbsoluteExpiration = DateTime.Now.AddSeconds(5);
cache.Set("CurrentDeveloper", d, ceo);
CUI.PrintStep("\nNun wird in einer Schleife der " +
"Zwischenspeicher zehnmal im Abstand von " +
"einer Sekunde nach dem Wert gefragt und "+
"die Statistik ausgeben.");
for (int i = 0; i < 10; i++)
{
Object result;
bool found = cache.TryGetValue("CurrentDeveloper", out result);
if (result is not null) CUI.Success(result);
else CUI.Warning("Cache ist leer!");
MemoryCacheStatistics stats = cache.GetCurrentStatistics();
Console.WriteLine(DateTime.Now);
Console.WriteLine(stats.ToNameValueString());
Console.WriteLine();
System.Threading.Thread.Sleep(1000);
var e = new FCL_MinimalEventCounterSource();
e.Write("x");
}
}
}
In der Ausgabe des obigen Listings sieht man, dass der Zwischenspeicher die ersten fĂĽnf Sekunden das gespeicherte Developer-Objekt liefert und die Zahl TotalHits
höher zählt. Danach gibt es kein Developer-Objekt mehr und TotalMisses
wird erhöht.
Noch ein Hinweis: Die Auswertung der genutzten Größe mit CurrentEstimatedSize
funktioniert nur, wenn im MemoryCache
-Objekt die Eigenschaft SizeLimit
belegt ist und bei Ablage eines Objekts im Cache dessen Größe per Eigenschaft Size
(oder Methode SetSize()
) angegeben wird. CurrentEstimatedSize
und Size
haben keine feste MaĂźeinheit. Die MaĂźeinheit muss man selbst festlegen. Im obigen Beispiel wird von Bytes ausgegangen.
(rme)