|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionBefore explaining cache management in ASP.NET, let me clarify that different people use different terms for explaining the same concept i.e. managing data. Some people refer to it as state management and some others refer to it as cache management. I love to use the term cache management, may be because I like the word "cache". But conceptually there is no difference between these two. Now let's discuss different aspects of cache management (or state management) in ASP.NET.
Although cache management is not an issue in Windows applications, it has always been a challenge in the web environment. Since HTTP is a stateless protocol and a web server doesn't recognize users between different requests, it becomes very important for us to recognize a particular user between different requests and also store data so that it can be re-used between different requests. ASP.NET provides many features for storing data both in the client (browser) and the server (web server) sides, but sometimes we get confused with when to use what. In ASP.NET we come across features like BackgroundIn this article, I will touch upon the different cache management options available in ASP.NET. In a web application, sometimes we require to store data in the server side to avoid costly data retrieval operation from data stores and time consuming data formatting logic to improve application performance as well as to re-use the same data in subsequent requests across users, applications and machines. So, to achieve this we need to store (cache) data in the server side. Caching helps us to achieve three important aspects of QoS (Quality Of Service):
Different optionsIn a web application, we can cache data, pages etc. both in server and client sides. Let us have a look at the different options available in ASP.NET for caching data both in server and client sides. Server side cache managementASP.NET session stateASP.NET session state is used to cache data per user session. It means that the data cannot be shared across multiple users and the data usage is limited to the user session it is created in. ASP.NET ASP.NET session state can be managed in three different ways:
Both in StateServer and SQLServer options, we need to ensure that the objects we cache are serializable as data storages are out-of-process systems. Both these options have impact on the application performance as data retrieval and saving operations take more time when compared to the InProc option. So based on our application requirement we should choose the option that best suits our requirement. The following example shows how the string empNum = Request.QueryString["empnum"];
if (empNum != null)
{
string details = null;
if (Session["EMP_DETAILS"] == null)
{
//Get Employee Details for employee number passed
string details = GetEmployeeDetails(Convert.ToInt32(empNum));
Session["EMP_DETAILS"] = details;
}
else
{
details = Session["EMP_DETAILS"];
}
//send it to the browser
Response.Write(details);
}
ASP.NET application objectASP.NET provides an object called ASP.NET cache objectASP.NET cache object is my favorite caching mechanism. That's why I love to talk more about it. ASP.NET provides a key-value pair object - the Although both Let us discuss the different expiration policies and the dependencies that are supported. DependencyDependency means that an item can be removed from the cache when a dependent entity gets changed. So a dependent relationship can be defined on an item whose removal from the cache will depend on the dependent. There are two types of dependencies supported in ASP.NET.
The following example shows how File dependency can be used to invalidate the cache item. So whenever the errors.xml file changes the cache item will automatically get expired and will be removed from the cache. object errorData;
//Load errorData from errors.xml
CacheDependency fileDependency =
new CacheDependency(Server.MapPath("errors.xml"));
Cache.Insert("ERROR_INFO", errorData, fileDependency);
The following example shows how Key dependency can be used to invalidate the cache items. string[] relatedKeys = new string[1];
relatedKeys[0] = "EMP_NUM";
CacheDependency keyDependency = new CacheDependency(null, relatedKeys);
Cache["EMP_NUM"] = 5435;
Cache.Insert("EMP_NAME", "Shubhabrata", keyDependency);
Cache.Insert("EMP_ADDR", "Bhubaneswar", keyDependency);
Cache.Insert("EMP_SAL", "5555USD", keyDependency);
Expiration policyExpiration policy sets the policy for how and when an item in the cache should expire.
//Absolute Expiration
Cache.Insert("EMP_NAME", "Shubhabrata", null,
DateTime.Now.AddDays(1), Cache.NoSlidingExpiration);
//Sliding Expiration
Cache.Insert("EMP_NAME", "Shubhabrata", null,
Cache.NoAbsoluteExpiration, TimeSpan.FromSeconds(60));
How to know when an item is removed?In the above examples we learned how to remove an item from the cache but sometimes we want to know when an item is removed from the cache. Yes, it is possible by using cache callbacks. In the error details example shown above, the cached item expires whenever the errors.xml file changes. Suppose we want to update the cache with the latest error details. To find out when the error details are removed from the cache we can use cache callback for further processing (reloading the error details again to the cache). The following example shows how to use cache callback to handle the item expiration scenario: private void AddItemsToCache()
{
int empNum = 5435;
CacheItemRemovedCallback onEmpDetailsRemove =
new CacheItemRemovedCallback(EmpDetailsRemoved);
Cache.Insert("EMP_NUM", empNum, null,
Cache.NoAbsoluteExpiration,
Cache.NoSlidingExpiration,
CacheItemPriority.Default,
onEmpDetailsRemove);
}
private void EmpDetailsRemoved(string key, object val,
CacheItemRemovedReason reason)
{
//When the item is expired
if (reason == CacheItemRemovedReason.Expired)
{
//Again add it to the Cache
AddItemsToCache();
In the above example you must have noticed the parameter .NET remotingYou might be thinking how .NET remoting can be used for data caching? The same question came to my mind when I heard about it for the first time. As you know the .NET remoting singleton object shares the same instance with multiple clients so singleton objects can be used to store and share data between different client invocations. Since .NET remoting can be used outside the process and machine, this option is very useful when we want to cache data and share it across servers and users particularly in a web farm scenario. In this approach we can store the data as member variables of singleton remoting object and provide methods to read and save data. But while implementing this we need to ensure that the remoting object used as cache is not destroyed by the garbage collector. For that we will have to set the remoting cache object's lease period to infinite so that the lease period never times out. We can do that by overriding the Memory-mapped filesYou all know what a memory-mapped file is. It is basically about mapping a file on disk to a specific range of addresses in the application's process address space. This option allows different processes to use the same data by increasing the application performance. As using memory-mapped file is not very popular among .NET developers, I would personally not suggest this approach as implementing this involves a lot of complexities and also .NET Framework doesn't support this. But if anyone is very much interested in using this approach then they will have to develop their own custom solution as per their own requirement. Static variablesWe use static variables for storing data or objects globally so that it can be accessed during the life of the application. Similarly, in ASP.NET we can use static objects for caching data and we can also provide methods to retrieve and save data to the cache. As static variables are stored in the process area, performance wise it is faster. But since it is very difficult to implement expiration policies and dependencies incase of static variables, I generally prefer ASP.NET cache object over this option. Another problem is that the custom static cache object has to be thread-safe which has to be implemented carefully. Custom static cache object can be defined as shown below: public class CustomCache
{
//Synchronized to implement thread-safe
static Hashtable _myCache =
Hashtable.Synchronized(new Hashtable());
public static object GetData(object key)
{
return _myCache[key];
}
public static void SetData(object key, object val)
{
_myCache[key] = val;
}
}
DatabaseWe can also use a database for storing data and sharing the data across users and machines. This approach is very useful when we want to cache large amounts of data. Using this approach for storing small amount of data is not a good idea because of performance. For storing small amount of data we should go for other ASP.NET in-process caching mechanisms. As the data needs to be stored in a database all the objects need to be XML serialized so that it is easier to store and retrieve. We can also use other types of serialization formats available in the .NET Framework. ASP.NET page output cachingSometimes in our application in some pages the output generally doesn't change for a specific period of time. For example in a HR website, the salary details of an employee doesn't change very frequently and it changes only once in a month. Generally it changes only on the 1st day of every month. So during a month the salary details page will show the same details for a particular employee. So in this case isn't it a good idea to cache the page somewhere in the server to avoid business calculation processing, calls to database and page rendering logic every time the employee wants to see his salary details. In my opinion, Yes! It is a very good idea. To achieve this, ASP.NET provides a feature to store the output of a page in the server for a specific period of time. It also provides features to store a fragment of a page which is known as Page fragment caching. Here I am not going to talk much about Page Output Caching as there are other articles available in the Internet that cover this mechanism in detail. This would a very lengthy section if I start discussing it. I am planning to cover this in another article. <!-- VaryByParm - different versions of same page will be
cached based on the parameter sent through HTTP Get/Post
Location - where the page is cached -->
<%@OutputCache Duration="60" VaryByParam="empNum"
Location="Server"%>
Let us do a comparison between the different options that we have discussed so far:
Client side cache managementIn the previous sections we discussed about the different caching options available in the server side but sometimes we may need to cache data or pages in the client side to improve application performance. Using this mechanism reduces the load on server but this mechanism has some security issues as we cache the data in client side. There are different options available for client-side caching. I am going to talk briefly about a few of them. CookiesCookie is a very familiar term in web development environment. Cookie is a client-side storage that is sent to the server for each request and also received as response back from the server. Because of its size limitation (4096 bytes) it should be used for storing small amount of data. Expiration policies can be set for cookies to invalidate the items after a certain period of time. The following example shows how Cookie can be used in an ASP.NET application: if (this.Request.Cookies["MY_NAME"] == null)
{
this.Response.Cookies.Add(new HttpCookie("MY_NAME",
"Shubhabrata Mohanty"));
}
else
{
this.Response.Write(this.Request.Cookies["MY_NAME"].Value);
}
ViewStateASP.NET ViewState is a new concept. Here the data related to the pages and controls are stored in ViewState which retains the values across multiple requests to the server. If you remember correctly, in VB-ASP applications we used to store data across multiple requests using hidden fields. ViewState is actually implemented internally as hidden fields in ASP.NET but here the data is hashed to improve security as against hidden fields. To see how ViewState is implemented, you can view the source of the page in which ViewState is used in the Internet browser. ViewState should not be used to store large amounts of data as it is passed to the server for each request. protected void Page_Load(object sender, EventArgs e)
{
if (this.ViewState["MY_NAME"] == null)
{
this.ViewState["MY_NAME"] = "Shubhabrata Mohanty";
}
//txtName is a TextBox control
this.txtName.Text = this.ViewState["MY_NAME"].ToString();
}
Hidden fieldsHidden fields are very popular among VB-ASP web developers. Hidden field is similar to any other control in a page but the visible state of this control is always <!--In ASP.NET-->
<asp:HiddenField ID="myHiddenField" Value="Shubhabrata"
runat="server" />
<!--In HTML-->
<input id="myHiddenField" type="hidden" value="Shubhabrata" />
Microsoft Internet Explorer cachingSince I am talking about ASP.NET then why not discuss about another caching capability from Microsoft? Microsoft Internet Explorer provides caching mechanism to cache pages in the client side. This can be set using the ConclusionHope I have explained all the different options clearly. Now it's time to go back to our desk and start implementing each of these options. Implementing any of these options should be done purely on the basis of our application requirement and proper evaluation. I request all readers of this article to provide their valuable comments. Reference
|
|||||||||||||||||||||||||||||||||||||||||||||||||