Output Caching


Visual Basic .NET Unleashed
By Paul Kimmel
Table of Contents
Chapter 19.  ASP.NET Web Programming

Output Caching

Web Formsthe Page classdefine a Cache property. Cache functions like a data dictionary of name and values. By associating a key with an object in the cache, you can store processor- intensive data the first time you request it.

The ease with which you can use the cache is part of what makes it so powerful. Assume that you run a query on the code database that returns a DataTable of source code. You can store that DataTable in the cache. You can manipulate the data in the cache instead of requerying the database. If you modify data in the cache, you can update the database from the cache.

This is especially useful for CPU-intensive processes like sorting database queries. Instead of a thousand users all hitting the database, when the first user requests the data, it is cached with the application on the server, resulting in lower traffic between the Web application and the database.

The Page class contains a Cache property. The Cache works like a data dictionary (or collection). Include a bit of code to see if an item needs to be added to or is available in the cache, and you have a Web application that caches data. Listing 19.5 adds caching to the code database DataGrid browser, caching sorts to avoid requesting a particular sort from the database more than once. (The whole application is listed here to facilitate your understanding of the necessary changes.)

Listing 19.5 Caching processor-intensive tasks , like requesting sorted data from a database
  1:  Imports System.Data.OleDb  2:   3:  Public Class WebForm1  4:  Inherits System.Web.UI.Page  5:   6:   7:  [ Web Form Designer Generated Code ]  8:   9:  Private Function ConnectionString() As String  10:  Return "Provider=Microsoft.Jet.OLEDB.4.0;" & _  11:  "Data Source=c:\ inetpub\ wwwroot\ CodeDatabase\ data\ CodeDatabase.mdb"  12:  End Function  13:   14:  Private Function Query() As String  15:  Return "SELECT * FROM SOURCE"  16:  End Function  17:   18:  Private Function OrderBy(ByVal SortColumn As String) As String  19:  If (SortColumn = "") Then  20:  Return ""  21:  Else  22:  Return " ORDER BY " & SortColumn  23:  End If  24:  End Function  25:   26:  Private Function Query(ByVal SortColumn As String) As String  27:  Return Query() & OrderBy(SortColumn)  28:  End Function  29:   30:  Private Sub Page_Load(ByVal sender As System.Object, _  31:  ByVal e As System.EventArgs) Handles MyBase.Load  32:  'Put user code to initialize the page here  33:   34:  If (IsPostBack()) Then Exit Sub  35:  BindData(Query())  36:   37:  End Sub  38:   39:  Private Sub DataGrid1_PageIndexChanged(_  40:  ByVal source As System.Object, _  41:  ByVal e As System.Web.UI.WebControls. _  42:  DataGridPageChangedEventArgs)  43:   44:  DataGrid1.CurrentPageIndex = e.NewPageIndex  45:  BindData(Query(FSortColumn))  46:   47:  End Sub  48:   49:  Protected WithEvents DataGrid1 As _  50:  System.Web.UI.WebControls.DataGrid  51:  Protected WithEvents Label1 As _  52:  System.Web.UI.WebControls.Label  53:   54:  Private FSortColumn As String = ""  55:  Private Property SortColumn() As String  56:  Get  57:  Return FSortColumn  58:  End Get  59:  Set(ByVal Value As String)  60:  FSortColumn = Value  61:  Changed()  62:  End Set  63:  End Property  64:   65:  Private Overloads Sub BindData(ByVal SQL As String)  66:  Dim Adapter As New _  67:  OleDbDataAdapter(SQL, ConnectionString())  68:  Dim DataSet As New DataSet()  69:  Adapter.Fill(DataSet, "Source")  70:  BindData(DataSet.Tables("Source"))  71:  AddToCache(FSortColumn, DataSet.Tables("Source"))  72:  End Sub  73:   74:  Private Overloads Sub BindData(ByVal Table As DataTable)  75:  DataGrid1.DataSource = Table  76:  DataGrid1.DataBind()  77:  End Sub  78:   79:  Private Sub AddToCache(ByVal Column As String, ByVal Table As DataTable)  80:  If Not (CachedTable(Column) Is Nothing) Then Exit Sub  81:  CachedTable(Column) = Table  82:  End Sub  83:   84:  Private Property CachedTable(ByVal Column As String) As DataTable  85:  Get  86:  Return CType(Cache(Column), DataTable)  87:  End Get  88:  Set(ByVal Value As DataTable)  89:  If (Column = "") Or (Value Is Nothing) Then Exit Property  90:  Cache.Insert(Column, Value)  91:  End Set  92:  End Property  93:   94:  Private Sub Changed()  95:   96:  If (CachedTable(FSortColumn) Is Nothing) Then  97:  BindData(Query(FSortColumn))  98:  Label1.Text = "Ran Query"  99:  Else  100:  BindData(CachedTable(FSortColumn))  101:  Label1.Text = "From Cache"  102:  End If  103:   104:  End Sub  105:   106:  Private Sub DataGrid1_SortCommand(_  107:  ByVal source As Object, ByVal e As _  108:  System.Web.UI.WebControls.DataGridSortCommandEventArgs) _  109:  Handles DataGrid1.SortCommand  110:   111:  SortColumn = e.SortExpression  112:  End Sub  113:  End Class 

The bulk of the revisions occur between lines 65 and 104. An overloaded version of BindData was implemented to separate binding from SQL and binding from a DataTable. When we bind from SQL, we add the DataTable to the Cache (see line 71). The biggest change occurs in the Change method. If the sorted column was previously requested , the binding occurs from the cache rather than creating the adapter, running the query, creating the dataset, and binding from the DataSet's Tables collection.


Listing 19.5 wraps the Cache access in a property method; you don't have to do that. As a matter of technique, though, adding a property wrapper around the cache access allows us to add any additional constraints transparently . For example, in the listing, we don't try to add anything to the cache if the key or object is null.

There are a few salient points about general technique and the specific mechanics of caching that you should be aware of. The CachedTable property on lines 84 to 92 demonstrates an indexed property. Line 86 demonstrates how to retrieve an object from the page's cache and cast it to the type of the object we stored in the cache, a DataTable. Line 96 demonstrates how to inspect the cache using the key-value. If there is no cached DataTable for a specific column, we call BindData; our BindData accesses the database. On the other hand, if the cache contains a DataTable for a particular column, we bind the data from the cache (see line 100).

Adding and Removing Cached Items

The System.Web.Caching.Cache class allows you to Add and Insert items into the cache. Insert supports four overloaded methods of varying degrees of difficulty. The Add method is not overloaded. The basic parameters of the two methods depend on which version of Insert or Add you call. IntelliSense and the help files will ably assist you on a case-by-case basis.

The following example shows the syntax of the Add method. Each argument (or return value) is described in Table 19.1.

 Public Function Add(_    ByVal key As String, _    ByVal value As Object, _    ByVal dependencies As CacheDependency, _    ByVal absoluteExpiration As DateTime, _    ByVal slidingExpiration As TimeSpan, _    ByVal priority As CacheItemPriority, _    ByVal onRemoveCallback As CacheItemRemovedCallback _) As Object 
Table 19.1. Arguments You Need to Supply to Cache.Add or Cache.Insert
Argument Description
Key The string value used to index the cache.
Value The object to be cached.
Dependencies CacheDependency used to determine validity of cached object.
AbsoluteExpiration DateTime indicates expiration of cached object.
SlidingExpiration Expiration interval from last access (see next subsection for an example).
Priority CacheItemPriority enumeration.
Object Return value. Equivalent to the Value argument passed to the Add method.
OnRemoveCallback Optional callback that will be raised when the item is removed from the cache.

The biggest difference between Add and Insert is that Insert replaces items with the same key and Add does not replace the item.

Setting an Expiration Time for Cached Items

The Cache class allows you to proactively manage the amount of data that ends up in the cache. As you might imagine, storing data tables for dozens or hundreds of users can become resource-intensive. By passing AbsoluteExpiration or SlidingExpiration arguments, you can control how long an object lives in the cache.

AbsoluteExpiration indicates how long an item can remain in the cache before it is removed. SlidingExpiration determines how long since the last access something can stay in the cache. For example, an AbsoluteExpiration of five minutes means that an item will be removed after five minutes has expired . A SlidingExpiration of five minutes means that the item will remain in the cache as long as someone accesses it within each five-minute interval or until the AbsoluteExpiration interval expires .


Visual BasicR. NET Unleashed
Visual BasicR. NET Unleashed
Year: 2001
Pages: 222

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net