Take Advantage of ASP.NET 2.0’s Data Caching Techniques, Part 2

Take Advantage of ASP.NET 2.0’s Data Caching Techniques, Part 2

ne of the major advances in ASP.NET 2.0 caching is support for SQL cache invalidation. This feature lets you retrieve or generate a rowset, usually as a DataSet or DataTable, and then hang on to it until the original source data changes. That removes the balancing act formerly required to refresh the data (invalidate the cached rowset) regularly enough to see recently updated values in the data source, yet still hang on to each cached copy long enough to get the required reduction in resource usage and retrieval time when reconstructing the rowset.

Now, with SQL Server versions 7.0, 2000 or 2005, you simply set up a dependency for the database and table(s) you are using, fetch and cache the rowset, and then keep using the cached copy until the database informs your application that the source data has changed. This can obviously provide a huge performance boost, with a corresponding reduction in response times and database/server resource usage.

Configuring SQL Cache Invalidation
In SQL Server 7.0 and SQL Server 2000, you have to pre-configure the database to support SQL cache invalidation, using a utility provided with version 2.0 of the .NET Framework. You’ll find this utility, named aspnet_regsql.exe, in the %windir%Microsoft.NETFramework[version] folder of your machine after installing .NET 2.0.

Figure 1. Preparing SQL Server 2000 for SQL Cache Invalidation: The figure shows change notification being configured on a SQL Server 2000 database named “delboy”, with the user ID “anon,” for the Northwind sample database and the table named Orders.

Configuring the database involves two steps:

  1. Enable your database for change notifications, which creates the change notification table and adds the required stored procedures:
  2.    aspnet_regsql.exe -S server -U user      -P password -d database -ed

  3. Enable the table(s) containing the data you are using, which adds the necessary row to the change notification table and adds the required triggers to the source data table:
  4.    aspnet_regsql.exe -S server -U user       -P password -d database -t table -et

If you are using a trusted connection to a local server, or a server on your network, you can replace the -S and -P parameters and values with just the empty parameter -E. Figure 1 shows change notification being configured on a SQL Server 2000 database named “delboy”, with the user ID “anon,” for the Northwind sample database and the table named Orders. Notice how the utility prompts for the password if you do not specify it in the command to execute aspnet_regsql.exe.

Figure 2. Cache Tables and Stored Procedures: After running aspnet_regsql.exe, you can see the new tables and stored procedures added to SQL Server 2000 for SQL cache invalidation.

Figure 2 shows the results. You can see the new table named AspNet_SqlCacheTablesForChangeNotification (so it’s not likely to clash with the name of an existing table), and in it the row for the Orders table. The lower section of the window shows the stored procedures used to implement the change notification.

SQL Server 2005 Change Notifications
While this technique does work with SQL Server 2005 (“Yukon”), you should prefer to use the built-in change notification service instead. The new Broker Service in SQL Server 2005 can be configured to monitor executed commands that return rowsets, and invalidate the cache automatically when any event occurs that could result in different values being returned if the same query were re-executed.

ASP.NET integrates with the Broker Service in SQL Server 2005, and can use the change notifications it produces to automatically invalidate output cached pages that use data generated through explicit code or the implicit commands it uses to extract data for the new data source controls.

Data Caching with a Data Source Control
ASP.NET 2.0 introduces a range of new data source controls that can, in many common scenarios, remove the requirement to write data access code. Most of these controls also implement caching, which plugs into the cache architecture automatically, and provides an easy way to boost the performance of your pages. As an example, the following code shows the attributes you can include when declaring a SqlDataSource control:

If the format of dates and times shown in these examples seems confusing, remember that the examples were created in England, so the date format is dd/mm/yyyy.

Simply by setting the EnableCaching attribute to True, and specifying the number of seconds to cache the data for the CacheDuration attribute, ASP.NET automatically caches the source data and reuses it when the page is refreshed during the specified duration period. However, note that this only works when the DataSourceMode is DataSet. You can also use a Sliding expiration policy (the default is Absolute), so that the cached data is invalidated only after there has been no request during the specified cache duration period.

Figure 3. Simple Finite Duration Caching in a SqlDataSource Control: The button updates the OrderDate column for the row with the OrderID 10248, causing the data in the cache to be out-of-sync with the data in the database.

To demonstrate the advantage of SQL cache invalidation, the sample code provides two examples that use a data source control. The first one, data-source-control.aspx, uses just the EnableCaching and CacheDuration attributes of a SqlDataSource control to force the data to be cached for a finite period?ten seconds in this example. The page also contains a button (see Figure 3) that causes a simple server-side routine to force an update within the source database of the OrderDate column for the first row that is shown in the page (OrderID = 10248) . Clicking the button updates the row, meaning that the data cached by the data source control is now out-of-date compared to the data in the source database row.

Notice that the SQL statement executed in Figure 3 updated the OrderDate of the first row to the current date and time, but the value displayed in the GridView control still shows the value when the rowset was originally fetched from the database. It’s only when the cache duration period expires that the GridView data is refreshed and the new value appears (see Figure 4).

Configuring a Database for Caching in Web.config
You can use the SqlCacheDependency attribute in a data source control (and in an OutputCache directive) to link cached rowset data to a SQL Server change notification. This solves the issue shown in the previous example, where the code and controls in the page are not aware that the source data has changed. SQL cache invalidation, implemented through change notifications, means that the page and controls can safely cache the data for long periods?but still show the correct values?by re-executing the query only when the data changes.

Figure 4. Updates Visible Only After Cache Expires: The updated row (the first row (compare to Figure 3) becomes visible only after the cache duration period expires.

As you saw earlier, SQL cache dependencies (for SQL Server 7.0 and 2000) are configured in machine.config or Web.config, using the section. You can clear from the list any databases that might be defined higher up in the configuration file hierarchy using the element, remove individual databases with the element, and add new ones using the element. The following example?adds a database cache entry named nwind-cache.


Notice that the default polling interval for all databases defined here is set to two seconds (2000 milliseconds), but specified as half a second for the “nwind-cache” entry (this is the minimum value you can use for the polling interval). Remember that you have to enable change notifications in the database for SQL Server 7.0 and 2000 using the aspnet_regsql.exe utility.

The connectionStringName attribute references the name of the connection string for this database, which you must declare in the section of this Web.config file, or in another configuration file higher up in the configuration hierarchy, as shown in the following example.


Using a SqlDependency with a Data Source Control
After configuring a SQL cache dependency, you can use it to enable change notification for a data source control (or in an OutputCache directive, as you’ll see shortly). The following declaration of a SqlDataSource control uses the nwind-cache entry:


If you want to base the cached data invalidation on more than one SQL cache dependency, you separate them with semicolons, for example:

Figure 5. Using a SQL Server 2000Cache Dependency with a Data Source Control: The main page caches the data indefinitely, but using the update page to update the Order Date causes the cache to refresh. Subsequent queries to the main page show the updated values.

The sample page data-source-sql2000.aspx demonstrates how to use a data source control with a SQL cache dependency, as described above. Figure 5 shows the example page, along with the new window that you can open from it to perform updates in the source database. The EnableCaching=”True” attribute in the data source control within the main page causes it to cache the rowset indefinitely (in other words, it doesn’t specify a CacheDuration attribute), so it shows the same rowset with each page refresh, without fetching it from the database again. However, the cached rowset data is invalidated automatically when you update the database using the button in the other browser window; after updating, the next refresh of the main page will shown the new value.

Using a SqlDependency in an OutputCache Directive
You can use the same SQL cache dependency described in the previous section for a data source control in an OutputCache directive in an ASP.NET page. The same syntax applies for using multiple dependencies:

   <%@OutputCache Duration="#seconds" VaryByParam="None"      SqlDependency="dependency-name:table-name" />


   <%@OutputCache Duration="#seconds" VaryByParam="None"      SqlDependency="dependency-name:table-name;      dependency-name:table-name" />
Figure 6. Using a SQL Server 2000 Cache Dependency in an OutputCache Directive: This example is equivalent to the one shown in Figure 5, but this time the main page contains a Duration attribute.

Figure 6 shows an example equivalent to the one in Figure 5, but this time using the SqlDependency in an OutputCache directive within the page, rather than in the data source control. The only visible difference is that this example displays the time at which the page was executed, so that you can confirm that the output is cached until the values in the source database table are changed by the other window.

You can also create database cache dependencies based on SQL Server 7.0 or SQL Server 2000 directly in code, using the SqlCacheDependency class added to the .NET Framework in version 2.0. Use an OutputCache directive in the page that specifies only the caching duration:

   <%@OutputCache Duration="#seconds" VaryByParam="None" />

Then, in the Page_Load event (or wherever required), create a new SqlCacheDependency instance and set this dependency on the output cache:

      ' database defined in Web.config as "nwind-cache",    ' dependency on Orders table   Dim dep As New SqlCacheDependency("nwind-cache", "Orders")   Response.AddCacheDependency(dep)

Using SQL Server 2005 Change Notifications
In SQL Server 2005, the Broker Service provides change notification automatically. You can create a dependency on a Command instance that generates the data for your page and attach it to the output cache in a similar way:

   ' for a SqlCommand instance named myCommand,    ' previously created in code   Dim dep As New SqlCacheDependency(myCommand)   Response.AddCacheDependency(dep)

You can also take advantage of dependencies in SQL Server 2005 using the special cache identifier value “CommandNotification” in your data source controls:


Or, in an OutputCache directive:

   <%@OutputCache Duration="#seconds" VaryByParam="None"      SqlDependency="CommandNotification" />
Author’s Note: The current Beta 2 release of SQL Server 2005, with ASP.NET 2.0 Beta 1, requires Windows XP SP2 or Windows Server 2003 SP1. Also, with common combinations of the Beta Framework and SQL Server 2005, the “CommandNotification” identifier is unreliable at the moment. However, the sample files include a page you can experiment with that’s equivalent to the example shown in Figure 5, except that it uses a SQL cache dependency with SQL Server 2005.

The final section of this article looks briefly at how you can use the Cache API provided with ASP.NET and the .NET Framework. Working with the Cache object in its simplest form is similar to using the Session and Application objects; however, the Cache provides many more opportunities to store and retrieve data, and to manage data priority and expiration.

The simplest approach uses the key name directly, though?as with the Session and Application objects?you should cast the returned value back to the correct data type:

   Cache("key-name") = value-to-cache   retrieved-value = CType(Cache("key-name"), object-type)

If the key name does not match an entry in the cache, it returns Nothing (null in C#). Remember that items may be ejected from the cache if memory or disk constraints demand it, and so you should test for the presence of a value and re-create it if it is not available?for example:

   Dim iMyValue As Integer = CType(Cache("myintvalue"), Integer)   If iMyValue Is Nothing Then     ' re-create the item     iMyValue =        {your code here to create or fetch the value again}     ' and add to cache     Cache("myintvalue") = iMyValue    End If

The Cache API also exposes two methods for adding items to the cache. The Insert method replaces any existing item with same key:

   Cache.Insert("key-name", value-to-cache)

The Add method fails if an item with the same key already exists in the cache, and returns the existing item instead. If the item does not exist, it is added to the cache and the method returns Nothing (null in C#):

   cached-item = Cache.Add("key-name", value-to-cache)
Author’s Note: See the .NET Framework SDK topic “Cache Members” in the “Reference | Class Library” section for more details.

Working with Cache Dependencies
Items added to the Cache can be dependent on a range of factors:

  • One or more disk files or folders
  • A fixed or sliding “last accessed” time span
  • An absolute date and/or time for expiration
  • Other cache dependencies (chained expiration)
  • Individual item priorities when the cache is purged

You can also detect when an item is removed from the cache using a callback, by handling the CacheItemRemoved event. Table 2 shows the full list of parameters for the Add and Insert methods of the Cache object, indicating how you specify the dependencies for an item when adding it to the Cache.

Table 2. The table lists the parameters for the Add and Insert methods of the Cache class.

keyA String that is the key name for the item in the cache.
valueAn Object that contains the value to be inserted into the cache.
dependenciesA reference to a CacheDependency instance. This can be a new instance based on any of the factors described in the bullet list above (the following sections detail the technique for creating these dependencies). Alternatively, it can be an existing dependency?so that when the existing dependency causes its cached data to be invalidated, the current data will also be invalidated.
absoluteExpirationA DateTime value that defines the time that the cached data will be invalidated.
slidingExpirationA TimeSpan that defines the length of time for which the cached data is valid.
priorityA CacheItemPriority value that controls how the item will be handled if the cache becomes full and items must be ejected automatically. The CacheItemPriority enumeration contains the values Default, High, AboveNormal, Normal, BelowNormal, and Low to specify the priority and allow items to be purged when available memory runs out, and the value NotRemovable (the default) to indicate that the item should not be removed.
onRemoveCallbackA reference to a CacheItemRemovedCallback instance, which will be executed when this item is invalidated and removed from the cache.

For example, to insert a new value, you can write:

   Cache.Insert("key", value, Nothing, _      DateTime.Now.AddMinutes(10), _      TimeSpan.Zero, CacheItemPriority.High, Nothing)

chCreating a CacheDependency
The dependencies parameter for the Add and Insert methods of the ASP.NET Cache object, shown in Table 2, is a reference to a CacheDependency instance that you create in your code. The CacheDependency class exposes several constructors, as shown in Table 3. These allow you to create a dependency that will invalidate the cached item in response to a range of events.

Table 3. The table lists the constructors for the CacheDependency class.

CacheDependency()Creates a CacheDependency with no dependent objects.
CacheDependency(“file/folder-path”)Creates a CacheDependency that will invalidate the cache when the specified file or folder (a String value) changes.
CacheDependency(array-of-file/folder-paths)Creates a CacheDependency that will invalidate the cache when any of the specified files or folders (an array of String values) change.
CacheDependency(“file/folder-path”,DateTime)Creates a CacheDependency that will invalidate the cache when the specified file or folder changes, or at the specified time.
CacheDependency(array-of-file/folder-paths,DateTime)Creates a CacheDependency that will invalidate the cache when any of the specified files or folders change, or at the specified time.
CacheDependency(array-of-file/folder-paths,array-of-cache-keys)Creates a CacheDependency that will invalidate the cache when any of the specified files or folders change, or any of the specified cache items (as an array of String values containing the cache keys) change.
CacheDependency(array-of-file/folder-paths,array-of-cache-keys, DateTime)Creates a CacheDependency that will invalidate the cache when any of the specified files or folders change, or any of the specified cache items change, or at the specified time.
CacheDependency(array-of-file/folder-paths,array-of-cache-keys,CacheDependency)Creates a CacheDependency that will invalidate the cache when any of the specified files or folders change, or any of the specified cache items change, or the specified CacheDependency causes its data to be invalidated.
CacheDependency(array-of-file/folder-paths,array-of-cache-keys,CacheDependency, DateTime)Creates a CacheDependency that will invalidate the cache when any of the specified files or folders change, or any of the specified cache items change, or the specified CacheDependency causes it’s data to be invalidated, or at the specified time.

Author’s Note: See the .NET Framework SDK topic “CacheDependency Members” in the “Reference | Class Library” section for more details.

Chaining Dependencies
Using the constructors for the CacheDependency class shown in Table 3, you can create chains of dependencies. This allows the invalidation of one dependency to force invalidation of the chained dependencies. For example:

   ' add an item that depends on the file myfile.xml,    ' and that expires after 10 minutes   Cache.Insert("first-key", myFirstValue, _      New CacheDependency(Server.MapPath("myfile.xml")), _      DateTime.Now.AddMinutes(10), TimeSpan.Zero, _      CacheItemPriority.High, Nothing)      ' create an array of file paths/names   Dim aFiles() As String   aFiles(0) = Server.MapPath("anotherfile.xml"),   aFiles(1) = Server.MapPath("astylesheet.xslt"),   Dim dep As New CacheDependency(aFiles, _      DateTime.Now.AddMinutes(25))      ' create an array with one cache key name   Dim aDeps() As String = {"first-key"}      ' create a SqlCacheDependency for the Northwind Orders table   Dim sqlDep As New SqlCacheDependency("nwind-cache", "Orders")      ' now add an item to the cache that depends on the three previous dependencies   Cache.Insert("second-key", mySecondValue, _      New CacheDependency(aFiles, aDeps, sqlDep), _      DateTime.Now.AddMinutes(10), TimeSpan.Zero, _      CacheItemPriority.High, Nothing)

Detecting Cache Invalidation
The onRemoveCallback parameter for the Add and Insert methods of the ASP.NET Cache object, shown in Table 2, is a reference to a delegate (event handler) that handles the CacheItemRemoved event. This event is raised when an item is removed from the cache for any reason, including invalidation through a dependency or through the cache becoming full?whereupon the least used and lowest priority items are removed.

You can handle the CacheItemRemoved event, and get information about the event, the item that was removed, and the reason:

   Sub MyItemRemoved(key As String, value As Object, _     reason As CacheItemRemovedReason)     ' reason will be one of:     ' Expired | Removed | Underused | DependencyChanged        ' re-create item and add back to cache as required   End Sub

Inside the event handler, you might decide to recreate the item and store it back in the cache (depending on the reason or some other factor), or take whatever other action is appropriate for your application. To register this event handler when you create a CacheDependency, you simply specify it as the last parameter of the Insert or Add method:

   Cache.Insert("key", value, Nothing, _      DateTime.Now.AddMinutes(10), _      TimeSpan.Zero, CacheItemPriority.High, _      New CacheItemRemovedCallback(AddressOf MyItemRemoved))
Author’s Note: See the .NET Framework SDK topic “CacheItemRemovedCallback Delegate” in the “Reference | Class Library” section for more details.

Figure 7. Cache API Features: The example page demonstrates some of the features of the Cache API.

The example page named cache-api.aspx demonstrates many of the features just described for using the Cache API, including adding different types of values with differing invalidation rules, creating a chained dependency, detecting cache invalidation, and enumerating the items stored in the Cache. Figure 7 shows the page, and you can see that it contains controls to refresh the page, insert a String value into the cache, add an array of Integer values to the cache, and insert a DataSet into the cache. Each item has a different set of properties for the created CacheDependency; for example it caches the String value from the Textbox with a ten second timeout using:

   Cache.Insert("MyTextBox", txtToCache.Text, Nothing, _      DateTime.Now.AddSeconds(10), _      TimeSpan.Zero, CacheItemPriority.High, _      New CacheItemRemovedCallback(AddressOf ItemRemoved))

However, it adds the array of Integers to the cache using the Add method, which fails if an item with the same key is already in the cache. The following code adds the array to the Cache object, tests whether it succeeded and displays the message in Figure 7 if the item already exists:

   ' add array of Integers to cache using Add method   Dim aInt() As Integer = {0,1,2,3,4}   If Not Cache.Add("MyIntArray", aInt, Nothing, _      DateTime.MaxValue, _      New TimeSpan(0, 0, 5), CacheItemPriority.High, _      New CacheItemRemovedCallback(AddressOf ItemRemoved)) _      Is Nothing Then      ' add warning to the StringBuilder that       ' displays messages in the page      op.Append(         "- item already exists, cache was not updated
") End If

Notice how, this time, the code specifies the expiration as a “sliding” time value so that it will expire five seconds after the last access, rather than at a fixed (“absolute”) time. To achieve this it specifies the absolute expiration parameter as DateTime.MaxValue, and the sliding expiration parameter as a TimeSpan instance.

You can see from the Figure 7 that the page also displays a list of items in the cache. It uses the following code to do this:

   ' display contents of the ASP.NET Cache   If Cache.Count > 0 Then     cc.Append("Contents of the ASP.NET Cache (" _        & Cache.Count.ToString() & " items):
") For Each item As Object In Cache cc.Append("Key:'" & item.Key & "' Type:" _ & item.Value.GetType().ToString() & "
") Next Else cc.Append("ASP.NET Cache is empty") End If ' show contents of StringBuilder in the Label control ' with the ID "cachecontents" cachecontents.Text = cc.ToString()
Figure 8. Output from the ItemRemoved Handler: The figure shows the messages displayed when the DataSet is removed from the cache.

In Figure 8, you can see another feature of this page. The code to add the DataSet to the cache looks like this:

   ' code here to create DataSet and fill with some rows   ' ......   ' create array containing cache key to depend on   Dim aKeys(0) As String   aKeys(0) = "MyTextBox"      ' create a dependency on the cache key in the array   Dim dep As New CacheDependency(Nothing, aKeys)      ' insert DataSet into Cache with dependency on    ' String value from Textbox   Cache.Insert("MyDataSet", ds, dep, _      DateTime.Now.AddMinutes(5), _      TimeSpan.Zero, CacheItemPriority.High, _      New CacheItemRemovedCallback(AddressOf ItemRemoved))

The result is that the DataSet can be cached only when the String value from the Textbox is also cached. The version 2.0 copy of this page also contains the event handler named ItemRemoved, which is referenced above in all the statements that create CacheDependency instances. This event handler executes when any item is removed from the cache. The following code shows the event handler.

   Sub ItemRemoved(key As String, value As Object, _      reason As CacheItemRemovedReason)         ' display details of item removed from cache and reason      op.Append("ItemRemoved event raised at " _         & DateTime.Now.ToString() & "
") op.Append("- removed item '" & key & "', Reason is '" _ & reason.ToString & "'
") End Sub

Figure 8 shows the output from this event handler when you try to add the DataSet to the cache without adding the String value first. However, this event handler runs only when a cache invalidation occurs while the page is executing.

Adding CacheDependencies Programmatically
You can also use the CacheDependency class with page output caching. To do that, create a CacheDependency instance, and assign it to the current ASP.NET page using the methods of the Response object. The HttpResponse class (in the System.Web namespace) implements the Response instance for an ASP.NET page, and has a series of properties and methods that you can use to manipulate the output cache settings for the page programmatically.

The AddCacheItemDependency method takes a String cache key name, and makes the output cache dependent on this item. Likewise, the AddCacheItemDependencies method does the same for the items specified by an ArrayList of cache key names. Meanwhile the AddFileDependency and AddFileDependencies methods do the same for a file path/name or an ArrayList of file path/names.

Author’s Note: See the .NET Framework SDK topic “HttpCachePolicy Members” in the “Reference | Class Library” section for more details.

The example page named file-dependency.aspx demonstrates how you can create a CacheDependency in code, and use it to control output caching of an ASP.NET page. It declares an OutputCache directive in the page that causes the whole page to be cached for five minutes, and does not vary the cache through any values (parameters) that may be posted to the page:

   <%@OutputCache Duration="300" VaryByParam="None" %>

The page also contains an XmlDataSource control that takes its data from an XML file named slides.xml located in the same folder as the page:

Figure 9. File Cache Dependency: The page shows the results of programmatically adding a CacheDependency for a disk file.

The remaining page content is a GridView that displays the data in the XML document, and a button to cause a postback. However, in the Page_Load event, code that runs when the page is executed not only displays the current time in a Label control at the top of the page, but also sets up a dependency on the slides.xml file:

   ' create File Dependency and attach to the cache   Dim dep As New CacheDependency(Server.MapPath("slides.xml"))   Response.AddCacheDependency(dep)

If you run this page (see Figure 9) and then refresh it, you’ll see that the server delivers the output-cached copy until the five minutes specified in the OutputCache directive have elapsed. However, if you open the XML file in a text editor and edit the values, you’ll see that the cached page is invalidated immediately, and the new values are displayed when you refresh the page.

Creating and Adding a SQL Server 2005 Cache Dependency
Adding a dependency to data stored in SQL Server is similar. The following code uses the AddCacheItemDependency method to create a dependency on a SqlCommand for a SQL Server 2005 database query, and adds it to the output cache for the page so that the page will be re-executed automatically whenever the data in the source table changes:

   Sub Page_Load()        ' display time page was executed     exectime.Text = "Page executed at " & _         DateTime.Now.ToString() & "
" Dim sSQL As String = "SELECT OrderID, CustomerID, " & _ "OrderDate, " & "Freight, ShipCity FROM Orders WHERE " & "OrderID < 10251" Using con As New SqlConnection( _ ConfigurationSettings.ConnectionStrings _ ("nwind").ConnectionString) Dim cmd As New SqlCommand(sSQL, con) ' create a SqlCacheDependency for the database ' defined in Web.config Dim dep As New SqlCacheDependency(cmd) Response.AddCacheDependency(dep) con.Open() grid1.DataSource = _ cmd.ExecuteReader(CommandBehavior.CloseConnection) grid1.DataBind() End Using End Sub

You've seen the primary techniques available in ASP.NET for caching values and data between user requests, as well as a discussion of the Cache object and output caching, with particular emphasis on the new features in version 2.0. At this point, you should feel comfortable with:

  • Choosing the right approach for caching data
  • Using Application, Session, and ViewState data caching
  • Global data caching using disk files
  • The ASP.NET output caching features
  • Using the ASP.NET Cache object directly

Your choice of caching technology depends mainly on the visibility required for the data, but also on the volume of data that you want to cache and the period for which it will be cached. You can store small volumes of data in the page ViewState, and larger volumes in the Session (for a specific user) or the Application (for all users of the application). Alternatively, you can use the ASP.NET Cache object and/or output caching to store large volumes of data and make it available across an application. For global caching where you want to make cached data visible across all applications and servers, however, you must implement something yourself. You saw how the .NET classes make this easy when caching data as disk files or in memory.

You can also consider taking advantage of how the combination of ASP.NET and SQL Server implement the new SQL cache invalidation feature. This feature lets you cache data for long periods without worrying about whether it will become stale. When the data in the data store changes, ASP.NET invalidates the cached data automatically and your code can obtain a fresh and up-to-date copy.

Finally, you've seen how you can create dependencies for all kinds of events, including changes to a file or folder, invalidation after a specific time period or at a specified time, and the invalidation of other cached items (to create dependency chains).

Using these techniques, you can boost performance and reduce server loading by selecting the appropriate caching technology, and implementing it in your applications. While there are no hard and fast rules on when and where you should use caching, and where it provides the greatest benefit, the usual rule of thumb is to consider caching any data that is expensive to create or retrieve, and that your application uses regularly. However, ultimately, you should be prepared to benchmark your applications to see where and how caching can provide optimum gains.


About Our Editorial Process

At DevX, we’re dedicated to tech entrepreneurship. Our team closely follows industry shifts, new products, AI breakthroughs, technology trends, and funding announcements. Articles undergo thorough editing to ensure accuracy and clarity, reflecting DevX’s style and supporting entrepreneurs in the tech sphere.

See our full editorial policy.

About Our Journalist