Server-Side State Management
Session
State: Its nothing but defined as a period of time shared between the web
application and user. Every user has individual session. Items/Objects can be
placed into the Session which would only define these objects for that user.
Session contains key variables which help to identify the related values. This
can be thought of as a hash table. Each user would represent a different key
node in the hash identifying unique values. The Session variables will be clear
by the application which can clear it, as well as through the timeout property
in the web config file. Usually the timeout is 20 minutes by default.
Session Variables are stored
on the server, can hold any type of data including references, they are similar
to global variables in a windows application and use HTTP cookies to store a key
with which to locate user's session variables.
The collection of session
variables is indexed by the name of the variable or by an integer index. Session
variables are created by referring to the session variable by name. You do not
have to declare a session variable or explicitly add it to the collection.
Lets get it cleared from
following example:
Session[“firstName”] =
“Gaurav” //User’s first name
Session[“lastName”] =
“Arora” //User’s last name
// Clear the session variable
Session[“FirstName”] = null;
//Clear all Session variables
Session.Abandon();
InProc—Stores Session state
in the same process as the ASP.NET process [aspnet_wp.exe].
StateServer—Stores Session
state in a Windows NT process, which is distinct from the ASP.NET
process[aspnet_state.exe].
SQLServer—Stores Session
state in a SQL Server database.
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.
Note:
By default, ASP.NET session
state is enabled for all ASP.NET applications.
ASP.NET application
object
ASP.NET provides an object
called Application object to store data that is accessible to all user requests.
The life span of this object is tied to the application and it is re-created
every time the application starts. Unlike ASP.NETSession object this object is
accessible to all user requests. Since this storage is created and maintained in
an application domain space, this should not be used for data storage in a web
farm scenario. This option is very useful to store data like the application
metadata (CONFIG files data) that can be loaded to the Application object during
application start up and can be used during the life of the application without
reloading it every time for each user request. But if there is a requirement to
invalidate the cached data whenever there is any change to the CONFIG files
while the application is running, this option should not be used as it doesn't
provide any feature to expire the cached data. So in this case other options
like the ASP.NET Cache object should be used, which is explained below.
Types of Cache
–Dependencies
When anyone add an item to
cache, he/she can define the dependency relationships that can force that item
to be removed from the cache under specific activities of dependencies.
For example: If the cache is
dependent on file and when the file data changes you want the cache object to be
updated.
Following are the difference
dependencies:
File Dependency :
Allows invalidating a
specific cache item when a disk based file or files change.
object errorData;
//Load errorData from
errors.xml
CacheDependency fileDependency
=
new
CacheDependency(Server.MapPath("errors.xml"));
Cache.Insert("ERROR_INFO",
errorData, fileDependency);
Time based expiration :
Allows to invalidate a
specific cache item depending on predefined time.
//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));
Key dependency :
Allows to invalidate a
specific cache item depending when another cache item changes.
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);
.NET remoting
You 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 InitializeLifetimeService method
of MarshalByRefObject and return null from this method. But the only issue with
this approach is performance. As the analysis says the performance is very poor
in this approach when compared to other approaches. Anyway it is up to the
application designers/developers to analyze different options and use the best
one that suits the requirement.
Memory-mapped files
You 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 variables
We 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.
Example:
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;
}
}
|