How to: Notify an Application When an Item Is Removed from the Cache
In most cache scenarios, when an item is removed from the cache, you do not have to be notified when it has been removed. The typical development pattern is to always check the cache for the item before using it. If the item is in the cache, you use it. If it is not in the cache, you retrieve the item again and add it back to the cache.
However, in some cases it is useful for your application to be notified when an item is removed from the cache. For example, you might want to track when and why items are removed from the cache in order to tune cache settings.
To enable notification of items being removed from the cache, ASP.NET provides the CacheItemRemovedCallback delegate. The delegate defines the signature for an event handler to call when an item is removed from the cache. Typically, you implement the callback by creating a handler in a business object that manages the cache data.
This topic explains how to handle a notification after an item has been removed from the cache. You can also be notified before an item has been removed. You can then prevent the item from being removed instead of re-creating the object. This might be more efficient for items that require a significant amount of processing time to re-create. For more information, see CacheItemUpdateCallback.
To notify an application after an item is removed from the cache
In a business class (not in a page or user control class), create a method that handles the callback when a cache item is removed. The method must have the same signature as the CacheItemRemovedCallback delegate.
You must make sure that this method is available when the cache item is deleted. Using a static class is one way to accomplish this. Note that in a static class, all static methods must be thread-safe.
Because the methods that add items to the cache and get items from the cache do not have to be available when the cache item is removed, it is common to put them in a separate class from the one that contains the callback handler.
Do not implement the method invoked by CacheItemRemovedCallback in a page, user control, or any other class that is repeatedly loaded and disposed, because the method might not be available when it is needed. In addition, pointing the callback to a method of an object can prevent the memory that is used by the object from being reclaimed by garbage collection. This happens because the callback contains a reference to the object and the garbage collector will not remove an item from memory if the item has any references. During periods of application load, this could cause memory to be used up very quickly.
In the callback method, add logic that will run when the item is removed from the cache.
The following example shows a class named ReportManager. The GetReport method of this class creates a report that consists of the string "Report Text". The method saves this report in the cache, and on subsequent calls it retrieves the report from the cache.
To simplify the example, the methods to manage the cache and the callback method are all in the same class. In a production environment, you typically separate these methods into separate classes.
If more than 15 seconds elapses between calls to GetReport, ASP.NET removes the report from the cache. When that event occurs, the ReportRemovedCallback method of the ReportManager class is called. This method sets a private member variable to "Re-created [date and time]", where [date and time] is the current date and time. The next time that GetReport is called after the cache item has expired, the method re-creates the report and appends the value of the variable that was set by the ReportRemovedCallback method to the report. The ShowReport.aspx page displays the report string that GetReport returns, which includes the date and time that the report was last re-created.
To see this behavior, load the page, wait more than 15 seconds, and then reload the page in the browser. You will see the date and time added to the report text.
Imports System Imports System.Text Imports System.Web Imports System.Web.Caching Public Class ReportManager Private Shared _lastRemoved As String = "" Public Shared Function GetReport() As String Dim report As String = CStr(HttpRuntime.Cache("MyReport")) If report Is Nothing Then report = GenerateAndCacheReport() End If Return report End Function Private Shared Function GenerateAndCacheReport() As String Dim report As String = "Report Text. " & _lastRemoved HttpRuntime.Cache.Insert( _ "MyReport", _ report, _ Nothing, _ Cache.NoAbsoluteExpiration, _ New TimeSpan(0, 0, 15), _ CacheItemPriority.Default, _ New CacheItemRemovedCallback(AddressOf ReportRemovedCallback)) Return report End Function Public Shared Sub ReportRemovedCallback(ByVal key As String, _ ByVal value As Object, ByVal removedReason _ As CacheItemRemovedReason) _lastRemoved = "Re-created " & DateTime.Now.ToString() End Sub End Class
<%@ Page Language="VB" AutoEventWireup="false" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> </head> <body> <form id="form1" runat="server"> <div> <%=ReportManager.GetReport()%> </div> </form> </body> </html>