Introduction
The concept of Caching was introduced in ASP.NET 1.X and has been improved significantly in ASP.NET 2.0. Caching allows you to store commonly used items in the memory and thus not create them from scratch when they are requested. There are different types of Caching available in the .NET framework. In this article I will introduce you to Caching dependencies.
Caching Dependencies
Caching can depend on several items which include user request, file, database tables, table rows, duration, user controls, query strings, browsers and also other cached items. Let's start with the Caching dependency on other cached items.
Caching Dependency on Cached Items
It is interesting to note that your cached item can depend on other cached items. This means that if the item A is removed from the cache you can also remove item B from the cache. Let's start by creating and inserting the item A and item B in the
Cache
object.protected void Button3_Click(object sender, EventArgs e)
{
// create item A and item B
string itemA = "ItemA";
string itemB = "ItemB";
Cache.Insert("ItemA", itemA, null, DateTime.Now.AddMinutes(10),
TimeSpan.Zero,
CacheItemPriority.Default, MyItemRemovedCallBack);
Cache.Insert("ItemB", itemB, null, DateTime.Now.AddMinutes(10),
TimeSpan.Zero,
CacheItemPriority.Default, MyItemRemovedCallBack);
}
In the code above I am creating two items "
It is not a good idea to insert the items into the Cache inside the callback method because you might not need the item right away and hence you will be wasting valuable resources to create them.
Let's take a look at the
itemA
" and "itemB
". After creating the items I simply put the items in the Cache
object using the Insert
method. The last parameter is the callback method "MyItemRemovedCallBack
" which will be fired when either of the two items is removed from the Cache.It is not a good idea to insert the items into the Cache inside the callback method because you might not need the item right away and hence you will be wasting valuable resources to create them.
Let's take a look at the
MyItemRemovedCallBack
implementation.private void MyItemRemovedCallBack(string key, object value,
CacheItemRemovedReason reason)
{
// remove the item from the cache
if (key == "ItemA" ) Cache.Remove("ItemB");
else if (key.Equals == "ItemB") Cache.Remove("ItemB");
}
The
MyItemRemovedCallBack
method takes three parameters.
key: This is the key which is used to identify the items in the Cache.
value: The value assigned to the item which is inserted in the Cache.
value: The value assigned to the item which is inserted in the Cache.
reason: The variable "reason" is of type
CacheItemRemovedReason
enumeration and it identifies the reason the item was removed from the Cache.
The code given below removes an item from the Cache and as soon as the item is removed the "
MyItemRemovedCallBack
" method is fired and removed the other item from the Cache.protected void Btn_RemoveCacheItem(object sender, EventArgs e)
{
Cache.Remove("ItemA");
}
Cache Dependency on a File
Next, let's see the Cache dependency on a file. Making the Cache dependent on the file means that when the file contents changes the Cache is expired and the contents are fetched again. Take a look at the simple XML file below which contains the information about the web site menu.
<?xml version="1.0" encoding="utf-8"?>
<MenuItems>
<MenuItem>
<Text>Home</Text>
</MenuItem>
<MenuItem>
<Text>About us</Text>
</MenuItem>
<MenuItem>
<Text>Contact us</Text>
</MenuItem>
<MenuItem>
<Text>Help</Text>
</MenuItem>
<MenuItem>
<Text>Feature</Text>
</MenuItem>
</MenuItems>
We will use the
Cache.Insert
method to make the Cache dependent on the file. Take a look at the code below:private void CreateMenu()
{
string menuPath = "MyFiles/Menu.xml";
string folderName = "MyFiles/";
DataSet ds = null;
if (Cache["Menu"] == null)
We will use the
Cache.Insert
method to make the Cache dependent on the file. Take a look at the code below:private void CreateMenu()
{
string menuPath = "MyFiles/Menu.xml";
string folderName = "MyFiles/";
DataSet ds = null;
if (Cache["Menu"] == null)
{
ds = new DataSet();
ds.ReadXml(Server.MapPath(menuPath));
// menu is created
Cache.Insert("Menu", ds, new System.Web.Caching.CacheDependency(
Server.MapPath(menuPath)),DateTime.Now.AddMinutes(60),
TimeSpan.Zero,
System.Web.Caching.CacheItemPriority.Default,
new System.Web.Caching.CacheItemRemovedCallback(
CacheItemRemovedCallBack));
DisplayCacheCreationTime("Object was not in the cache and created at:",
DateTime.Now.ToLongTimeString());
}
else
{
// menu is created from the cache
DisplayCacheCreationTime("Object was in the cache",String.Empty);
}
}
The
CreateMenu
method is responsible for creating the Cache dependency on a file. As, you can see I have used the DataSet's ReadXML
method to read the contents from the XML file and later inserted the DataSet
into the Cache. The CacheDependency
method is responsible for setting Cache dependent on the file. I have also included an ItemRemovedCallBack
callback method which is fired whenever the Cache dependency is expired (in this case whenever the file changes). If you execute the code above the first time the method CreateMenu
is executed it will read the contents from the file since, initially the Cache is empty but for all the later requests the contents are fetched from the Cache object.
You can also create a Cache dependency on the folder. This will mean that whenever a file or a subfolder is added, deleted then the Cache is expired and a new (fresh) copy is fetched.
Cache Dependency on SQL
One of the biggest improvements in ASP.NET 2.0 Caching is the feature of Cache dependency on database tables. This means that the data will be present in the Cache as long as the table entries does not change. As, soon as the database table is changed the Cache is expired. You can enable the SQL Cache dependency by using theaspnet_regsql.exe command line tool. Simply, type the following command on the Visual Studio.NET 2005 command line.
aspnet_regsql -ed -E -d School
The command above will enable the Cache dependency on the "School" database. The next step is to enable the caching on the individual table. You can do that by using the following line.
aspnet_regsql -et -E -d School -t Users
The above line will enable the caching on the Users table which is contained in the School database.
The next step is to create the
connectionString
in the connectionStrings
section andsqlCacheDependency
in the web.config file. Take a look at the code below:<connectionStrings>
<add name="ConnectionString"
connectionString="Server=localhost;Database=School;
Trusted_Connection=true"/>
</connectionStrings>
<system.web>
<caching>
<sqlCacheDependency pollTime="10000" enabled="true" >
<databases>
<add connectionStringName="ConnectionString" name="School"/>
</databases>
</sqlCacheDependency>
</caching>lt;/caching>
As, you have noticed that the
sqlCacheDependency
have a pollTime
attribute which is set to "1000" milliseconds. This means that the ASP.NET will check the database table for any changes every 10 seconds. The database section of the <caching>
contains the connectionString
which is used to connect to the database.
The final step is to use the caching in your code. You can do this in various ways. Take a look at the following code which uses caching programmatically.
private void BindData()
{
// if null then fetch from the database
if (Cache["Users"] == null)
{
// Create the cache dependency
SqlCacheDependency dep = new SqlCacheDependency("School", "Users");
string connectionString = ConfigurationManager.ConnectionStrings[
"ConnectionString"].ConnectionString;
SqlConnection myConnection = new SqlConnection(connectionString);
SqlDataAdapter ad = new SqlDataAdapter("SELECT FirstName, LastName " +
"FROM Users", myConnection);
DataSet ds = new DataSet();
ad.Fill(ds);
// put in the cache object
Cache.Insert("Users", ds, dep);
}
gvUsers.DataSource = Cache["Users"] as DataSet;
gvUsers.DataBind();
}
The line
SqlCacheDependency dep = new SqlCacheDependency("School", "Users");
is used to create the caching on the School database and Users table. In the beginning of the BindData
method I check that if the item is already in the Cache. If it is then I simply return the item using caller by casting it from the Cache object. If the item is not in the Cache then the data is fetched from the database and inserted into the Cache object. The Cache will be discarded anytime you make a change in the database table "Users". This means that if you INSERT, DELETE, UPDATE any data in any row in the Users table then the Cache will be considered obsolete and a copy of the fresh data will be fetched from the database.
Caching in SQL Server 2005 have a different architecture then in SQL Server 2000. You don't have to write any lines in web.config to enable Caching in SQL Server 2005. Also, in SQL Server 2005 the Cache is only expired when the row is changed in the database table.
No comments:
Post a Comment