7.15 Reuse Data with the ASP.NET Cache


Problem

You need to use caching, but you can't cache an entire page because it includes some code that must run or some content that must be generated dynamically.

Solution

Use the Cache.Insert method to store any object with a sliding or absolute expiration policy.

Discussion

The Cache object allows you to store almost any .NET object using a string key with the expiration policy you define. ASP.NET maintains the cache automatically, removing objects when they expire or when memory becomes scarce .

There are two types of expiration policies that you can use when storing data in the cache. Absolute expiration invalidates cached items after a fixed period of time, much like output caching. Absolute expiration is the best approach if you need to store information that needs to be periodically refreshed (such as a product catalog).

 // Store ObjectToCache under the key "Catalog" for 10 minutes. // TimeSpan.Zero indicates that we won't use sliding expiration. Cache.Insert("Catalog", ObjectToCache, null,   DateTime.Now.AddMinutes(10), TimeSpan.Zero); 

ASP.NET also supports a sliding expiration policy, which removes objects after a period of disuse. In this case, every time the object is accessed, its lifetime is reset. Sliding expiration works well when you have information that is always valid but is not always being used (such as historical data). This information doesn't need to be refreshed, but it shouldn't be kept in the cache if it isn't being used.

 // Store ObjectToCache under the key "Catalog" as long as it is being used // at least once every ten minutes. // DateTime.MaxValue indicates that we won't use absolute expiration. Cache.Insert("Catalog", ObjectToCache, null,    DateTime.MaxValue, TimeSpan.FromMinutes(10)); 

You can retrieve items from the cache by key name . However, you must always first check to see whether the item exists and then cast it to the desired type.

When adding objects to the cache, the best design pattern is to create a separate function that can re-create the object as needed. For example, if you're storing a DataSet , create a function that checks the cache and requeries the database only if the DataSet can't be found. This allows you to avoid the most time-consuming part of the page processingquerying the databasewhile still allowing your code to tailor the display (for example, apply a user - requested sort order) or perform other actions.

The next example demonstrates this pattern. It displays a table with customer information drawn from a DataSet . The key ingredient is the CustomerDatabase class, which encapsulates the functionality needed to fill the DataSet and manage the cache. Because this class doesn't inherit from Page , it needs to use the static HttpContext.Current property to retrieve a reference to the Cache object.

 using System; using System.Data; using System.Web; using System.Configuration; using System.Diagnostics; using System.Web.Caching; using System.Data.SqlClient; public class CustomerDatabase {     private string connectionString;     // Retrieve the reference to the Cache object.     private Cache cache = HttpContext.Current.Cache;     public CustomerDatabase() {              // Get the connection string from the Web.config file.         connectionString = ConfigurationSettings.AppSettings["NorthwindCon"];     }     public DataSet GetCustomers() {              DataSet customersDS;         // Check for cached item.         if (cache["Customers"] == null) {                      // Get DataSet from database.             customersDS = GetCustomersFromDatabase();                              // Store the item in the cache              // with a sliding expiration policy of 60 seconds.             cache.Insert("Customers", customersDS, null,               DateTime.MaxValue, TimeSpan.FromSeconds(60));             // Show a debug message.             Debug.WriteLine("DataSet created from data source.");         }else {                      // Show a debug message.             Debug.WriteLine("DataSet retrieved from cache.");                              // Retrieve the item.             customersDS = (DataSet)cache["Customers"];         }         // Return the DataSet.         return customersDS;     }     private DataSet GetCustomersFromDatabase() {              // Create the DataSet.         DataSet customersDS = new DataSet();                          // Fill the DataSet (from a file).         SqlConnection con = new SqlConnection(connectionString);         SqlCommand cmd = new SqlCommand("SELECT * FROM Customers", con);         SqlDataAdapter adapter = new SqlDataAdapter(cmd);         try {             con.Open();             adapter.Fill(customersDS, "Customers");         }catch {             customersDS = null;         }         finally {             con.Close();         } 

The next step is to create a Web page that uses the CustomerDatabase class. The following example shows a page with a DataGrid and a single Button . Every time the user clicks the Button , the page calls the CustomerDatabase.GetCustomers method. The information is retrieved from the cache if available or requeried if the 60-second time period has elapsed. You can determine whether the DataSet was retrieved from the cache by looking at the output in the Debug window.

 using System; using System.Web; using System.Web.UI.WebControls; public class LoginPage : System.Web.UI.Page {     protected System.Web.UI.WebControls.DataGrid DataGrid1;     protected System.Web.UI.WebControls.Button cmdGetData;     // (Designer code omitted.)     private void cmdGetData_Click(object sender, System.EventArgs e){         CustomerDatabase custDB = new CustomerDatabase();         DataGrid1.DataSource = custDB.GetCustomers();         DataGrid1.DataBind();     } } 



C# Programmer[ap]s Cookbook
C# Programmer[ap]s Cookbook
ISBN: 735619301
EAN: N/A
Year: 2006
Pages: 266

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