Tipps und Tricks rund um .NET und Visual Studio

Framework Class Library Caching ExpandoObject und Datenübertragung zwischen Streams
Kommentare

In dieser Episode von .NETversum geht es um die Framework Class Library und wie man damit eine eine Cache-Implementierung für Webapplikationen betreibt, auf die Klasse ExpandoObject zurückgreifen kann sowie Datenübertragung zwischen Streams realisiert.

Caching für alle: Das .NET-Framework enthält seit seinen ersten Tagen eine Cache-Implementierung – allerdings lediglich für Webapplikationen. Um auch andere Applikationen von Caching-Mechanismen profitieren zu lassen, werden entsprechende Konstrukte ab Version 4 für sämtliche Applikationen über den Namespace System.Runtime.Caching in der gleichnamigen Assembly angeboten. Die damit bereitgestellte Implementierung ähnelt jener von ASP.NET und sieht zurzeit lediglich einen In-Memory-Cache (MemoryCache) vor. Weitere Cache-Implementierungen können jedoch durch Ableiten von der Basisklasse ObjectCache entwickelt werden.

Ein Beispiel für die Verwendung von MemoryCache findet sich in Listing 1. Zunächst wird hier über die statische Eigenschaft MemoryCache.Default eine Referenz auf die global bereitgestellte Standardinstanz von MemoryCache bezogen und versucht, über den Schlüssel someText einen gecachten String abzurufen. Konnte er nicht ermittelt werden, wird der Eintrag aus einer Datei gelesen und unter dem mit ihm assoziierten Schlüssel someText im Cache abgelegt. Im Zuge dessen wird auch eine CacheItemPolicy übergeben, die festlegt, wann der Cache-Eintrag wieder aus dem Cache entfernt werden soll. Dazu wird mit der Eigenschaft SlidingExpiration festgelegt, nach welchem Zeitraum, in dem nicht auf das Element zugegriffen wird, dieses Element zu entfernen ist. Daneben bietet Priority vom Enum-Typ CacheItemPriority die Möglichkeit, zu definieren, dass ein Eintrag gar nicht aus dem Cache entfernt werden soll. Das wird mit dem Wert NotRemovable angezeigt. Zusätzlich zur SlidingExpiration wird auch ein ChangeMonitor vom Typ HostFileChangeMonitor registriert. Er überwacht die an den Konstruktor übergebenen Dateien und/oder Ordner auf Änderungen. Im Fall einer Änderung werden die mit der Policy assoziierten Einträge aus dem Cache entfernt. Neben dem HostFileChangeMonitor existiert auch ein SqlChangeMonitor, der eine Instanz der seit .NET 2.0 verfügbaren Klasse SqlDependency kapselt und sie zur Überwachung von Änderungen in einer SQL-Server-Datenbank (ab Version 2005) verwendet. Weitere derartige Mechanismen können durch Ableiten von der Basisklasse ChangeMonitor oder einer deren Subklassen bereitgestellt werden (Listing 1).

Listing 1

const string source = @"c:tempsomeTextFile.txt";
ObjectCache cache = MemoryCache.Default;
string fileContents = cache["someText"] as string;

if (fileContents == null)
{
    Console.WriteLine("Element war nicht (mehr) im Cache! ");
    CacheItemPolicy policy = new CacheItemPolicy();
    policy.SlidingExpiration = TimeSpan.FromSeconds(50);

    List filePaths = new List();
    filePaths.Add(source);
    policy.ChangeMonitors.Add(new HostFileChangeMonitor(filePaths));

    fileContents = File.ReadAllText(source);
    cache.Set("someText", fileContents, policy);
}
Console.WriteLine(fileContents);  

ExpandoObject: Für Fälle, in denen lediglich ein dynamisches Objekt benötigt wird, welches das freie Definieren von Eigenschaften und Methoden erlaubt, kann seit .NET 4.NET 4.0 auf die Klasse ExpandoObject zurückgegriffen werden. Listing 2 demonstriert die Verwendung dieser Klasse. Zunächst werden dem Objekt die Eigenschaften FirstName und LastName hinzugefügt, anschließend bekommt es eine Methode DoStuff, die als Lambda-Ausdruck übergeben wird, spendiert. Danach werden die beiden Eigenschaften wieder ausgelesen und die Methode wird aufgerufen.

Listing 2

dynamic whatever = new ExpandoObject();
whatever.FirstName = "Max";
whatever.LastName = "Mustermann";
whatever.DoStuff = new Action(() => Console.WriteLine("Hello World!"));

Console.WriteLine(whatever.FirstName + " " + whatever.LastName);
whatever.DoStuff();  

Übertragen von Daten zwischen Streams: Jeder, der schon einmal mit Streams gearbeitet hat, kennt Routinen, die blockweise aus einem Stream lesen und diese Blöcke in einen anderen Stream schreiben. Für solche Fälle besitzt die Klasse Stream seit .NET 4.NET 4.0 aber auch eine Methode CopyTo, die den Stream, an den die Daten gesendet werden sollen, entgegen nimmt. Eine Überladung dieser Methode nimmt zusätzlich eine Blockgröße in Byte entgegen. Sie gibt an, wie groß die zu überbetragenden Blöcke sein sollen. Der Standardwert wurde hierfür auf 4096 festgelegt. Listing 3 zeigt ein Beispiel für den Einsatz dieser Methode. Die aus dem Streams input gelesenen Daten werden in den Stream output. kopiert.

Listing 3

public static void CopyStreamSample()
{
FileStream input;
FileStream output;

using (input = new FileStream(@"c:tempa.txt", FileMode.Open))
{
   using (output = new FileStream(@"c:tempb.txt", FileMode.CreateNew))
   {
      input.CopyTo(output);

    }
}
}  
Dr. Holger Schwichtenberg (MVP) und FH-Prof. Manfred Steyer arbeiten bei www.IT-Visions.de als Softwarearchitekten, Berater und Trainer für .NET-Technologien. Dabei unterstützen Sie zahlreiche Unternehmen beim Einsatz von .NET und entwickeln selbst in größeren Projekten. Sie haben zahlreiche Fachbücher geschrieben und gehören seit vielen Jahren zu den Hauptsprechern auf der BASTA. Manfred Steyer ist zudem verantwortlich für den Fachbereich „Software Engineering“ der Studienrichtung „IT und Wirtschaftsinformatik“ an der FH CAMPUS 02 in Graz. Dr. Holger Schwichtenberg unterrichtet in Lehraufträgen an den Fachhochschulen Münster und Graz.
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -