Contact   •   Products   •   Search

Rick Strahl's Web Log

Wind, waves, code and everything in between...
ASP.NET • C# • HTML5 • JavaScript • AngularJs

ASP.NET Cache and Session State Storage


Ok, I feel that I should have known this before, but until I tested this for myself today I wasn’t really sure and didn’t quite consider the implications.

 

Somebody on the Universal Thread asked about using the Cache object to store a DataSet and then reusing it. I replied not really thinking about this, saying that the DS gets serialized and then each new Cache request retrieves that instance from the serialized store.

 

Well, of course this is incorrect.

 

The Cache object lives inside the current AppDomain (ie. ASP.NET Application Scope) and it stores its entries in a Hashtable. When you store a reference object like a DataSet you are actually storing a live reference of that object, which means if you make a change to that object it’s reflected in all other clients that are trying to read that object or currently hold a reference.

 

The same is true with the Application object. With the Session object on the other hand it depends on how you store the object – InProc uses a live reference, but if you’re going to StateServer or SQLServer the reference is serialized:

 

Object

Entry Storage

Cache Object

Live Reference

Application Object

Live Reference

Session (InProc)

Live Reference

Session(StateServer/Sql Server)

Serialized Reference

 

 

What’s a bit surprising is that when I went looking for this information I couldn’t really dig up an entry that describes exactly what gets stored in the various State saving mechanisms. So I ran a very simple test using code like this:

 

// Put user code to initialize the page here

CacheItemTest T = this.Cache["Test"] as CacheItemTest;

if (T == null)

{

      T = new CacheItemTest();

      this.Cache["Test"] = T;

}

Response.Write("Cache: " + T.IntVal.ToString() + "<p>");

T.IntVal = T.IntVal +1;

 

where CacheItemTest is defined as:

 

public class CacheItemTest

{

      public int IntVal = 0;

      public string StrVal = "Rick";

      public int Counter = 0;

}

 

If you run this you’ll see that the counter keeps going up on every request, which means that when we change the property we’re changing the live object that lives now both in our reference and a reference that the Cache object holds.

 

This has some fairly serious implications if you are updating data in this object. If you’re expecting that object to stay in a fixed state once pulled out of the Cache that will obviously not happen. This could also have implicit complications if you are dealing with an object stored that is not thread safe! For example, if you run some internal operation on an object that internally affects the state of the object by changing a field value this will affect the state of the object for the next caller or even one that already has a reference. For example, if there was some internal counter used to walk through a list and the counter was upped each time you went on to the next entry, and two requests did this at the same time the counter would get trashed and you’d get serious garbage. This is not a great example – after all that’s what iterators are for – but it gives you an idea.

 

It’s clear that Cache’d objects should be read only objects – unless you treat it like the multi-threaded and multi-referenced object that it actually is and handle synchronization properly. In this respect the Cache object behaves not much different than a pure static object reference. The advantage of Cache is that it handles object assignment synchronization so you’re guaranteed that an object gets created only once (which is a concern with statics in busy thread situations).

 

Session Object

It gets more interesting with the Session object. Consider this code adjusted for use with a Session object:

 

CacheItemTest TS = this.Session["Test"] as CacheItemTest;

if (TS == null)

{

      TS = new CacheItemTest();

      this.Session["Test"] = TS;

}

Response.Write("Session: " + TS.IntVal.ToString());

TS.IntVal = TS.IntVal +1;

 

With InProc Sessions the Cache object behaves as with the Cache object with an increasing counter: You’re pointing to a reference object that is returned to you from a Hashtable.

 

Now go into your web.config and change the operation to StateServer. The first thing that happens is that you get an error:

 

Unable to serialize the session state. Please note that non-serializable objects or MarshalByRef objects are not permitted when session state mode is 'StateServer' or 'SQLServer'.

 

What this means is that our type is not serializable so I have to add:

 

[Serializable]

 

to the type. Now it works…

 

I was actually surprised to see the behavior exactly the same as with InProc objects. Even though objects serialize ASP. Net tracks objects locally and writes out any changes out to the stateserver.

 

To see what’s happening I hooked up SQLServer Session state and fired up the SQL Monitor to watch what actually fires.

 

It appears that the Session object writes out the current Session, always, no matter whether you use it or not (assuming EnableSessionState is on on the page). There are no read operations once a session has been loaded once which means ASP.NET manages a copy in memory. But at the end of every hit the entire content of the session state gets dumped to the StateServer in what looks like binary serialization.

 

This means:

 

  1. You don’t have to write objects back to a session – it happens automatically
  2. Once you read an object it always gets written back whether you’ve touched it or not!
  3. You get all of the overhead of session serialization even if you don't use it or if you change a single value

 I didn’t really get the second point until today – in fact in most of my apps I have something like this:

 

Session["Test"] = TS;

 

when the Session entry exists already and this has basically no effect at all.

 

It’s pretty important to understand these things when dealing with state stores. Obviously it would be a pretty big problem if you have huge amounts of state in your Session object as you’re sending all of this to the Session store EVERY time on every page hit!

 

For InProc objects there’s obviously a hell of a lot less overhead, since it doesn’t have any of this serialization and storage overhead. For Cache objects you have to be aware of the fact that you’re dealing essentially with an object accessed across multiple threads, so make sure that you are only using thread-safe objects and you don’t write data to these objects unless you write the proper synchronization code.

Make Donation


Feedback for this Post

 
# re: ASP.NET Cache and Session State Storage
by Bob Archer December 23, 2004 @ 3:22am
Rick,

You can also set the page session to ReadOnly. I forget how but this is supposed to be more performant. I have seen many optimizing ASP.Net app articles/session say this. If you make your page class default to this, and only change it to read/write on the pages that write/change session data.

Of course, if you are using InProc I can't see that there will be that much difference since it is just an inmemory reference.

BOb
# re: ASP.NET Cache and Session State Storage
by Bob Archer December 23, 2004 @ 3:23am
Also, isn't the Cache object just a member of the Application object?

BOb
# re: ASP.NET Cache and Session State Storage
by Rick Strahl December 23, 2004 @ 7:01pm
Cache is a member of HttpContext (or indirectly of Page). Cache and Application are very different animals. There really isn't any need for Application any longer since you can use Statics or the Cache for that sort of a thing. Note that this object represents not HttpApplication, but HttpApplicationState.

As to ReadOnly sessions, yes that makes sense. It's important to be explicit, but I bet that most pages that use sessions do both read and write operations.

It's just interesting that I have been stuck in the mode of 'serialization' when thinking about all of these objects rather than thinking of them as live object references that are not immutable and need to be explicitly updated.

It's very cool that this works the way it does and another one of those 'ASP.NET does things for you that you had to manuyally manage before'...

# re: ASP.NET Cache and Session State Storage
by Phil Smith December 29, 2004 @ 3:42am
I have been asked to migrate a non-public ASP web application that operates using a web farm and uses SQL Server for session state storage.

I have a gut feeling that the overhead involved in using SQL Server to manage session state storage nullifies the the advantages of having the web farm. Any rules of thumb on this, like you need at least n web servers to justify the performance hit of using SQL Server to manage session state?

Also, when SQL Server is being used to store session state, do you think it is better to use viewstate instead of session to persist small amounts of data?

Thanks in advance for any responses you may be inclined to offer.
# re: ASP.NET Cache and Session State Storage
by Rick Strahl December 29, 2004 @ 9:53am
Phil, while hte overhead is not little I doubt that it will have that drastic of an effect. Remember that basically what happens is that you have hte overhead of serialization plus a single database hit to write the data. If your data is data driven in the first place will an extra SQL access (which is the real overhead) really kill your app? Doubtful...

Also look into State Service first - it is a bit more efficient than SQL Server - given SP1 of 1.1 I haven't seen any more problems like the one that started off this entry.

Remember also Web Farm is not all about performance either - scalability and redundancy are the key to a Web Farm by wideneing the incoming base for hits...
# OdeToCode Links For Dec 30
by OdeToCode Link Blog December 30, 2004 @ 4:03am
# Facts about stroing objects in Sessions, Cache, Application....
by Saravana's Blog December 30, 2004 @ 5:55pm
Facts about stroing objects in Sessions, Cache, Application....
# re: ASP.NET Cache and Session State Storage
by anil February 21, 2005 @ 8:27pm
can i use this Session or Cache object when I am using WebFarm for Load balancing?
# re: ASP.NET Cache and Session State Storage
by Rick Strahl February 21, 2005 @ 8:38pm
You can use Session with SessionServer or Sql Server logging types. Caching will cache on each machine since the cache is entirely in memory.
# re: ASP.NET Cache and Session State Storage
by Warren Connors March 11, 2005 @ 9:28pm
Also re performance hit of SQL Server session state mgt, a critical factor is where your database server is in relation to the web servers, in terms of actual network hop routing and physical distance. I worked on an ASP.NET application awhile back in which we had 3 web servers and a database server bolted in right next to each other in a rack, with 6-foot long gigabit ethernet cables going to a gigabit switch in the rack. In a situation like that SQL Server session state mgt performance was great. Obviously the farther away the web servers and database server are from each other in network routing/distance terms, the performance can be proportionately decreased.
# re: ASP.NET Cache and Session State Storage
by Kevin March 31, 2005 @ 8:33am
Storing the connection string in plain text in the web.config file is a security risk that I'm not comfortable with. Is there another alternative?
# re: ASP.NET Cache and Session State Storage
by Rick Strahl March 31, 2005 @ 12:56pm
# Why you shouldn't use InProc Session State in ASP.NET
by Rick Strahl's WebLog April 20, 2005 @ 3:49pm
InProc sessions in ASP.NET are very volatile due to ASP.NET's processing model. While much faster, InProc sessions are very susceptable to unloading which often has nasty results for the users on your site. Here's a summary of some of the ways that InProc session can unload.
# re: ASP.NET Cache and Session State Storage
by jay June 29, 2005 @ 10:33am
you said you add [Serializable] to the type...

what type and where do you add that? thanks.
# re: ASP.NET Cache and Session State Storage
by Muhammad Rashid July 12, 2005 @ 2:17am
When i copy as it is code and run my application it gives me a new exception "Unable to make the session state request to the session state server. Please ensure that the ASP.NET State service is started and that the client and server ports are the same. If the server is on a remote machine, please ensure that it accepts remote requests by checking the value of HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\aspnet_state\Parameters\AllowRemoteConnection.
". now please tell me what should I do?
# re: ASP.NET Cache and Session State Storage
by hairsh August 03, 2005 @ 9:26pm
session and cache stores live reference then what is the difference between them
# re: ASP.NET Cache and Session State Storage
by Rick Strahl August 04, 2005 @ 9:14am
The Session object is user specific and thus times out items when the user session times out. Session is accessible only by a given user. Cache is global. Different purposes for different needs.
# re: ASP.NET Cache and Session State Storage
by Vijay October 10, 2005 @ 8:31am
Rick - You have mentioned that, "Caching will cache on each machine since the cache is entirely in memory. "

Does that mean that you can cache data in the application and the data will be stored in 3 places (assuming that there are 3 servers in a web farm?)

I was told by my friend that we might have some issues when we use caching in a load balancing environment since the cache will not be stored in all the servers. Hence thought of checking it. Any thoughts on this will be very helpful.
# re: ASP.NET Cache and Session State Storage
by Rick Strahl October 10, 2005 @ 9:23am
Vijay,

Yes Caching is machine specific at least in the out of the box solution. This means in a Web Farm each box will have a separate cache and in some instances this can cause problems if the Caches are out of sync. If one cache expires and refreshes before another you may see the content flipping back and forth which is not good...

There are third party solutions for cache implementations that use a database, but some of that defeats the purpose of caching in that there's some overhead.

Basically in a Web farm environment you have to think carefully about what to cache. If you have content that can cache but updates frequently then caching may not be a good choice. OTOH, if your cached content is mostly static and stays fairly constant then you're probably Ok.
# re: ASP.NET Cache and Session State Storage
by kremlins November 18, 2005 @ 11:50am
apllication and cache store live reference then what is the difference between them ?

# ASP.NET Session Management w/ SQL Server
by TheChaseMan's Frenetic SoapBox February 04, 2006 @ 9:45am
# which is best Session or cache in asp.net
by Pankaj March 12, 2006 @ 9:52pm
which is best Session or cache in asp.net
# re: ASP.NET Cache and Session State Storage
by keyur shah March 23, 2006 @ 6:16pm
Muhammad Rashid
you need to give admin privileges on your sql server machine or machine on which state service is running for the user of the machine on which iis is running.
# re: ASP.NET Cache and Session State Storage
by Archia May 07, 2006 @ 10:52pm
Rick,
I have a scenerio in which i am saving a hashtable in state using session mode as SQLServer. The hashtable stores keys and values where key is is a serializable checkbox and value is some text. when i retrieve the hashtable from the state, the key property (checkbox checked property is set to true when it was false at the time of saving that into state) Due to this checkboxes are getting automatically selected in my page at the time of post back.
# re: ASP.NET Cache and Session State Storage
by Rick Strahl May 08, 2006 @ 3:20pm
A hashtable key value is not the actual object, but a hash, so the checkbox is not actually storing. I'm not sure how you are restoring this object and have it work at all, but it certainly won't give you back a checkbox and its values.
# re: ASP.NET Cache and Session State Storage
by Jey May 16, 2006 @ 9:20am
Rick,
I faced a problem when I used the session object. I store a dataset in the session till the user saves the data to the db. Now this works fine for all users except for 2. When these 2 users login and navigate from base page to modal pop up's they loose the session information. I am sure the session is not expiring. Also when I checked what the session ID's were like (I logged them), it were diferrent for each response for these 2 users! For other users they are always the same. These two users are domain admins at our location. Any idea why this could happen?

Right now I switched to cache and wrote a custom sync code to maintain the cache info.
# re: ASP.NET Cache and Session State Storage
by Rick Strahl May 16, 2006 @ 11:17am
Sessions require Cookies unless you're using Cookieless Sessions. Make sure those people have cookies enabled.
# re: ASP.NET Cache and Session State Storage
by Jey May 22, 2006 @ 9:55am
yes..I did check that. Infact I asked him to try in my machine where it works fine for me. Interestingly it failed when he logged into the application. :-(
# re: ASP.NET Cache and Session State Storage
by vijendra May 30, 2006 @ 1:36am
can we share cache objects between applications. For example i have 2 virtual directories in my website and i like to share cache object between these.
# re: ASP.NET Cache and Session State Storage
by Rick Strahl May 30, 2006 @ 2:12am
No you can't share...
# re: ASP.NET Cache and Session State Storage
by Steve from Pleasant Hill August 29, 2006 @ 4:25pm
I find this topic to be very relevant and mostly misunderstood. Vital for any developer.

"Performance tips" people stress turning off Session Read and/or Write for each page whenever possible, and this explains why.

It also explains why my data still was updated even though I had forgot to specifically update the Session var myself.

Good stuff.
# Why you shouldn't use InProc Session State in ASP.NET - Rick Strahl's Web Log
by Rick Strahl's Web Log October 09, 2006 @ 12:17am
InProc sessions in ASP.NET are very volatile due to ASP.NET's processing model. While much faster, InProc sessions are very susceptable to unloading which often has nasty results for the users on your site. Here's a summary of some of the ways that InProc session can unload.
# ASP.NET Forums - Simultaneous modifying a disconnected dataset in Cache?
by State Management December 05, 2006 @ 3:13pm
# ASP.NET Forums - asp.net Cache and user context
by State Management May 15, 2007 @ 5:46am
# Caching in a web farm - ASP.NET Forums
by ASP.NET Forums May 18, 2007 @ 6:40am
# asp.net Cache and user context - ASP.NET Forums
by ASP.NET Forums May 18, 2007 @ 7:40am
# re: ASP.NET Cache and Session State Storage
by Narendra July 04, 2007 @ 1:55am
Good Stuff
# Simultaneous modifying a disconnected dataset in Cache? - ASP.NET Forums
by ASP.NET Forums July 12, 2007 @ 11:53am
# re: ASP.NET Cache and Session State Storage
by Dean Bennett February 21, 2008 @ 7:16am
I am planning on using the cache with a dataset to imporve the perfomance of a web service I have created. This web service is basically only there to server up an instance of a legacy COM dll. I found a great post about how to make legacy COM dll's multithread.

http://msdn.microsoft.com/msdnmag/issues/06/10/WickedCode/

Since the COM dll was created in VB 6, it is thread safe. Therefore I think my solution will not have any of the issues with thread synchronization you mention. Do you agree?
# re: ASP.NET Cache and Session State Storage
by Karthic October 21, 2008 @ 11:20pm
Will Storing Complex Objects (Like hashTable & Class objects ) into Session needs serialization & deserialization

Could you brefiely explain any specific steps need to be taken to setup my web appln ready for load balancing

I have used form authentication,viewstate..... in my web site
# re: ASP.NET Cache and Session State Storage
by Sarah Williams December 03, 2008 @ 6:11am
Great work Rick!

I see that you have mentioned that the in-process nature of ASP.NET cache does pose problems in case of sessions. So true! In fact the in-process and standalone nature of ASP.NET isn't very scalable and reliable either. For more info on this please follow the link provided.
http://www.alachisoft.com/ncache/asp-net-cache.html

All the best!
# re: ASP.NET Cache and Session State Storage
by Abhijeet January 12, 2009 @ 5:07am
Is there any way to configure IIS to clear cache at the end of every session? What are pros and cons?
# re: ASP.NET Cache and Session State Storage
by Troy (bbqchickenrobot) February 18, 2009 @ 2:13pm
Instead of using AlachiSoft and their NCache product which is proprietary and NOT free - check out Shared Cache an free and open source (source code available) .NET project!! It's fast and offers the same benefits and more that all the other cache servers use (i.e. - memcache, Java Objects, Shop.Com's Cache, NCache...etc...) - plus it's also a Native .NET application.

check it out at http://www.sharedcache.com
# re: ASP.NET Cache and Session State Storage
by dotnetguts June 11, 2009 @ 4:13am
It was helpful description.

Thanks
# re: ASP.NET Cache and Session State Storage
by eric August 12, 2009 @ 3:10pm
I've always been curious about how to make cached data read only. For example if you were working with the NorthwindDatabase, perhaps you might have a method called GetProductsByCategoryId(int catId). You would return a List of objects (let's say ProductInfo objects). The key for storing the data in the Cache might be "GetProductsByCategory<catId>" where the catId would be the value passed into the method. My question is how can I return a list of objects that are Read Only?
# re: ASP.NET Cache and Session State Storage
by Umar Jamil August 19, 2009 @ 3:06am
@ eric
hey eic,
one way to do so is to use and additional API, NCache express, and use its Object Query Language(OQL) feature. I came accross this caching API when I was developing an OE tool for one of my clients.
When Icame across this blog, and after reading it till your post, I was convinced that all of us can use it according to our needs, from session caching to object caching, keeping data upto dated and getting the fresh data at any time using its write through and read through features. As it is a distributed caching solution, it gives us the capability to share data between and cache object.

you can get it from: http://www.alachisoft.com/download.html
# re: ASP.NET Cache and Session State Storage
by Phillip September 29, 2009 @ 5:11am
Rick (et al.),
I have a c# web page (3.5) with sessionState mode="StateServer".
I've also set the EnableSessionState="True" on the Page Directive of the page.

I load up a DataView object to a variable named "dv" and then try to save the dataview object to a session ... "Session["Source"] = dv" ...
and get the infamous error

"Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode."

StateServer service is running fine. I can save string variables or int variables (etc.), but I can't seem to save anything like an object or dataview, etc.

Can you advise why any object I try to save to session gives me this error? I have put the [Serializable] declaration on every class that exists (even the ones from the two other referenced projects in my solution, and still get the same error.

I got the same thing in another scneario trying to save a custom class (with [Serializable] declared on the class) to session ... Session["oContract"] = poContract.
I've tried everything I can find by googling.
Hopefully someone here can provide some insight.

Phillip
# re: ASP.NET Cache and Session State Storage
by James March 16, 2010 @ 2:58am
Hello Rick.

I have the same problems.

I use the 'SQLServer' mode to storage session.
But I am very sure that I don't put any unserialization object into session.

In the same program, it can work well in normal, but if some unknow trouble is happend
and get the infamous error

"Unable to serialize the session state. In 'StateServer' and 'SQLServer' mode, ASP.NET will serialize the session state objects, and as a result non-serializable objects or MarshalByRef objects are not permitted. The same restriction applies if similar serialization is done by the custom session state store in 'Custom' mode."

For solving this error, I must execute 'iisreset' and i don't have any idea about why the error happen.

Can you advise how to analyse the trouble?

James
# re: ASP.NET Cache and Session State Storage
by Nav March 29, 2010 @ 11:16am
James:Do you have any delegates or events declared in your custom classes? You need to add [field:NonSerialized] attribute to event fields.
 


West Wind  © Rick Strahl, West Wind Technologies, 2005 - 2014