Gewusst wie: Benachrichtigen einer Anwendung beim Entfernen eines Elements aus dem Cache
Aktualisiert: November 2007
In den meisten Szenarios müssen Sie ein Element, das aus dem Cache entfernt wird, dem Cache erst dann wieder hinzufügen, wenn es erneut benötigt wird. Die normale Vorgehensweise beim Entwickeln ist es, der Verwendung eines Elements stets die Prüfung voranzustellen, ob das Element im Cache vorhanden ist. Wenn sich das Element im Cache befindet, kann es verwendet werden. Wenn es sich nicht im Cache befindet, müssen Sie es erneut abrufen und dem Cache hinzufügen.
In einigen Fällen ist es jedoch sinnvoll, die Anwendung beim Entfernen eines Elements aus dem Cache zu benachrichtigen. Gehen wir z. B. von einem zwischengespeicherten Bericht aus, für dessen Erstellung eine relativ lange Verarbeitungszeit erforderlich ist. Der Bericht soll nach dem Entfernen aus dem Cache sofort neu generiert und im Cache abgelegt werden, damit der Benutzer bei der nächsten Anforderung nicht erst die Verarbeitung abwarten muss.
Für das Benachrichtigen beim Entfernen eines Elements aus dem Cache stellt ASP.NET den CacheItemRemovedCallback-Delegaten bereit. Der Delegat definiert die Signatur, die Sie zum Schreiben eines Ereignishandlers verwenden können, der beim Entfernen eines Elements aus dem Cache aufgerufen wird. Mithilfe der CacheItemRemovedReason-Enumeration von ASP.NET kann außerdem die Ursache für das Entfernen eines Elements aus dem Cache angegeben werden.
Um den Rückruf zu implementieren, wird in der Regel ein Handler in einem Geschäftsobjekt erstellt, das die speziellen abzurufenden Cachedaten verwaltet. Gehen wir beispielsweise davon aus, dass Sie ein ReportManager-Objekt verwenden, das über die Methoden GetReport und CacheReport verfügt. Die GetReport-Methode überprüft, ob der Bericht bereits im Cache vorliegt. Wenn dies nicht der Fall ist, generiert die Methode den Bericht neu und legt ihn im Cache ab. Die CacheReport-Methode verfügt über dieselbe Funktionssignatur wie der CacheItemRemovedCallback-Delegat. Beim Entfernen des Berichts aus dem Cache ruft ASP.NET die CacheReport-Methode auf, worauf der Bericht dem Cache erneut hinzugefügt wird.
So benachrichtigen Sie eine Anwendung beim Entfernen eines Elements aus dem Cache
Erstellen Sie eine Klasse zum Abrufen des Elements aus dem Cache und zum Behandeln der Rückrufmethode für das erneute Hinzufügen des Elements zum Cache.
Erstellen Sie in der Klasse eine Methode, die dem Cache ein Element hinzufügt.
Erstellen Sie in der Klasse eine Methode, die ein Element aus dem Cache abruft.
Erstellen Sie eine Methode, die den Rückruf bei der Entfernung des Elements aus dem Cache behandelt. Die Methode muss über dieselbe Funktionssignatur verfügen wie der CacheItemRemovedCallback-Delegat. Fügen Sie der Methode die Logik hinzu, die beim Entfernen eines Elements aus dem Cache ausgeführt werden soll (z. B. erneutes Generieren des Elements und erneutes Hinzufügen zum Cache).
So testen Sie den Cacheelementrückruf
Erstellen Sie eine ASP.NET-Webseite, die die Klassenmethode zum Hinzufügen des Elements zum Cache aufruft.
Das folgende Codebeispiel zeigt, wie Sie die GetReport-Methode der ReportManager-Klasse aufrufen. (Die entsprechende Definition finden Sie in den Codebeispielen am Ende des Themas.) Anschließend wird der Bericht beim Ausführen der Page_Load-Methode der Seite in einem Label-Steuerelement mit dem Namen Label1 angezeigt.
protected void Page_Load(object sender, EventArgs e) { this.Label1.Text = ReportManager.GetReport(); }
Protected Sub Page_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load Me.Label1.Text = ReportManager.GetReport() End Sub
Fordern Sie die ASP.NET-Seite in einem Browser an, um den Bericht anzuzeigen.
Der Bericht wird bei der ersten Anforderung der Seite erstellt. Bei allen darauffolgenden Anforderungen erfolgt der Zugriff auf den Bericht so lange über den Cache, bis der Bericht wieder aus dem Cache entfernt wird.
Beispiel
Das folgende Codebeispiel zeigt eine vollständige Klasse mit dem Namen ReportManager, die die Benachrichtigung beim Löschen eines Elements aus dem Cache behandelt. Die Klasse verwaltet einen Bericht in Form einer Zeichenfolge, der einen zeitintensiven Prozess darstellt.
Auch wenn im Beispiel eine als static deklarierte Klasse verwendet wird (Visual Basic: Shared), müssen Sie nicht zwingend eine statische Klasse verwenden. Die den Rückruf behandelnde Methode muss jedoch beim Löschen des Cacheelements vorhanden sein. So sollten Sie z. B. den Rückrufhandler nicht in einer ASP.NET-Seite implementieren, da die Seite beim Löschen des Elements aus dem Cache möglicherweise bereits verworfen wurde und deswegen die Methode zum Behandeln des Rückrufs nicht mehr zur Verfügung steht. Indem Sie für die den Rückruf behandelnde Methode eine statische Klasse verwenden, wird sichergestellt, dass die Methode beim Entfernen des Elements aus dem Cache noch vorhanden ist. Der Nachteil einer statischen Klasse ist jedoch, dass alle statischen Methoden threadsicher sein müssen.
Vorsicht: |
---|
Legen Sie CacheItemRemovedCallback nicht auf eine Methode in einer Seite fest. Nicht nur eine Methode auf einer Seite, die nach dem Verwerfen der Seite nicht mehr für den Rückruf zur Verfügung steht, sondern auch ein Rückruf, der auf eine Methode in der Seite zeigt, kann verhindern, dass der von der Seite verwendete Arbeitsspeicher von der Garbage Collection zurückgefordert wird. Gründe dafür sind ein Verweis des Rückrufs auf die Seite und die Tatsache, dass der Garbage Collector keine Elemente mit Verweisen aus dem Speicher entfernt. Bei Ladevorgängen der Anwendung ist der Arbeitsspeicher deshalb möglicherweise sehr schnell ausgelastet. |
Die Beispielklasse verfügt über folgende Features:
Einen privater Member, um nachzuverfolgen, ob der Bericht aus dem Cache entfernt wurde.
Eine Methode mit dem Namen CacheReport, die dem Cache ein Element mit dem Namen MyReport hinzufügt, das eine Minute nach dem Hinzufügen zum Cache abläuft. Die Methode übergibt außerdem die ReportRemovedCallback-Methode an den onRemoveCallback-Parameter, der die ReportRemoveCallback-Methode registriert, sodass diese beim Löschen des Elements aus dem Cache aufgerufen wird.
Eine Methode mit dem Namen GetReport, die das Element aus dem Cache abruft. Die Methode überprüft, ob das Element mit dem Namen MyReport im Cache vorhanden ist. Wenn das Element nicht vorhanden ist, ruft die Methode die CacheReport,-Methode auf, die dem Cache das Element hinzufügt.
Eine Methode mit dem Namen ReportRemovedCallback, die den Rückruf bei der Entfernung eines Elements aus dem Cache behandelt. ReportRemovedCallback verfügt über dieselbe Funktionssignatur wie der CacheItemRemovedCallback-Delegat. Die Methode legt die Variable _reportRemovedFromCache auf true fest und fügt dem Cache das Element anschließend über die CacheReport-Methode erneut hinzu.
using System;
using System.Web;
using System.Web.Caching;
public static class ReportManager
{
private static bool _reportRemovedFromCache = false;
static ReportManager()
{ }
public static String GetReport()
{
lock (typeof(ReportManager))
{
if (HttpContext.Current.Cache["MyReport"] != null)
return (string)HttpRuntime.Cache["MyReport"];
else
{
CacheReport();
return (string)HttpRuntime.Cache["MyReport"];
}
}
}
public static void CacheReport()
{
lock (typeof(ReportManager))
{
HttpRuntime.Cache.Add("MyReport",
CreateReport(), null, Cache.NoAbsoluteExpiration,
new TimeSpan(0, 1, 0),
System.Web.Caching.CacheItemPriority.Default,
new CacheItemRemovedCallback(ReportRemovedCallback));
}
}
private static string CreateReport()
{
System.Text.StringBuilder myReport =
new System.Text.StringBuilder();
myReport.Append("Sales Report<br />");
myReport.Append("2005 Q2 Figures<br />");
myReport.Append("Sales NE Region - $2 million<br />");
myReport.Append("Sales NW Region - $4.5 million<br />");
myReport.Append("Report Generated: " + DateTime.Now.ToString()
+ "<br />");
myReport.Append("Report Removed From Cache: " +
_reportRemovedFromCache.ToString());
return myReport.ToString();
}
public static void ReportRemovedCallback(String key, object value,
CacheItemRemovedReason removedReason)
{
_reportRemovedFromCache = true;
CacheReport();
}
}
Imports System
Imports System.Web
Imports System.Web.Caching
Public Class ReportManager
Private Shared _reportRemovedFromCache As Boolean = False
Shared Sub New()
End Sub
Private Sub New()
End Sub
Public Shared Function GetReport() As String
SyncLock (GetType(ReportManager))
If HttpContext.Current.Cache("MyReport") IsNot Nothing Then
Return CStr(HttpRuntime.Cache("MyReport"))
Else
CacheReport()
Return CStr(HttpRuntime.Cache("MyReport"))
End If
End SyncLock
End Function
Public Shared Sub CacheReport()
SyncLock (GetType(ReportManager))
HttpRuntime.Cache.Add("MyReport", CreateReport(), _
Nothing, Cache.NoAbsoluteExpiration, New TimeSpan(0, 1, 0), _
System.Web.Caching.CacheItemPriority.Default, _
New CacheItemRemovedCallback(AddressOf ReportRemovedCallback))
End SyncLock
End Sub
Private Shared Function CreateReport() As String
Dim myReport As New System.Text.StringBuilder()
myReport.Append("Sales Report<br />")
myReport.Append("2005 Q2 Figures<br />")
myReport.Append("Sales NE Region - $2 million<br />")
myReport.Append("Sales NW Region - $4.5 million<br />")
myReport.Append("Report Generated: " & _
DateTime.Now.ToString() & "<br />")
myReport.Append("Report Removed From Cache: " _
& _reportRemovedFromCache.ToString())
Return myReport.ToString()
End Function
Public Shared Sub ReportRemovedCallback(ByVal key As String, _
ByVal value As Object, ByVal removedReason _
As CacheItemRemovedReason)
_reportRemovedFromCache = True
CacheReport()
End Sub
End Class
Siehe auch
Aufgaben
Gewusst wie: Hinzufügen von Elementen zum Cache
Gewusst wie: Abrufen von Werten von zwischengespeicherten Elementen
Gewusst wie: Löschen von Elementen aus dem Cache in ASP.NET