Rick Strahl's Weblog  

Wind, waves, code and everything in between...
.NET • C# • Markdown • WPF • All Things Web
Contact   •   Articles   •   Products   •   Support   •   Advertise
Sponsored by:
West Wind WebSurge - Rest Client and Http Load Testing for Windows

ASP.NET Cache and Session State Storage


:P
On this page:

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.


The Voices of Reason


 

Bob Archer
December 23, 2004

# re: ASP.NET Cache and Session State Storage

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

Bob Archer
December 23, 2004

# re: ASP.NET Cache and Session State Storage

Also, isn't the Cache object just a member of the Application object?

BOb

Rick Strahl
December 23, 2004

# re: ASP.NET Cache and Session State Storage

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'...


Phil Smith
December 29, 2004

# re: ASP.NET Cache and Session State Storage

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.

Rick Strahl
December 29, 2004

# re: ASP.NET Cache and Session State Storage

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 Link Blog
December 30, 2004

# OdeToCode Links For Dec 30


Saravana's Blog
December 30, 2004

# Facts about stroing objects in Sessions, Cache, Application....

Facts about stroing objects in Sessions, Cache, Application....

anil
February 21, 2005

# re: ASP.NET Cache and Session State Storage

can i use this Session or Cache object when I am using WebFarm for Load balancing?

Rick Strahl
February 21, 2005

# re: ASP.NET Cache and Session State Storage

You can use Session with SessionServer or Sql Server logging types. Caching will cache on each machine since the cache is entirely in memory.

Warren Connors
March 11, 2005

# re: ASP.NET Cache and Session State Storage

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.

Kevin
March 31, 2005

# re: ASP.NET Cache and Session State Storage

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?

Rick Strahl
March 31, 2005

# re: ASP.NET Cache and Session State Storage


Rick Strahl's WebLog
April 20, 2005

# Why you shouldn't use InProc Session State in ASP.NET

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.

jay
June 29, 2005

# re: ASP.NET Cache and Session State Storage

you said you add [Serializable] to the type...

what type and where do you add that? thanks.

Muhammad Rashid
July 12, 2005

# re: ASP.NET Cache and Session State Storage

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?

hairsh
August 03, 2005

# re: ASP.NET Cache and Session State Storage

session and cache stores live reference then what is the difference between them

Rick Strahl
August 04, 2005

# re: ASP.NET Cache and Session State Storage

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.

Vijay
October 10, 2005

# re: ASP.NET Cache and Session State Storage

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.

Rick Strahl
October 10, 2005

# re: ASP.NET Cache and Session State Storage

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.

kremlins
November 18, 2005

# re: ASP.NET Cache and Session State Storage

apllication and cache store live reference then what is the difference between them ?


TheChaseMan's Frenetic SoapBox
February 04, 2006

# ASP.NET Session Management w/ SQL Server


Pankaj
March 12, 2006

# which is best Session or cache in asp.net

which is best Session or cache in asp.net

keyur shah
March 23, 2006

# re: ASP.NET Cache and Session State Storage

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.

Archia
May 07, 2006

# re: ASP.NET Cache and Session State Storage

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.

Rick Strahl
May 08, 2006

# re: ASP.NET Cache and Session State Storage

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.

Jey
May 16, 2006

# re: ASP.NET Cache and Session State Storage

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.

Rick Strahl
May 16, 2006

# re: ASP.NET Cache and Session State Storage

Sessions require Cookies unless you're using Cookieless Sessions. Make sure those people have cookies enabled.

Jey
May 22, 2006

# re: ASP.NET Cache and Session State Storage

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. :-(

vijendra
May 30, 2006

# re: ASP.NET Cache and Session State Storage

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.

Rick Strahl
May 30, 2006

# re: ASP.NET Cache and Session State Storage

No you can't share...

Steve from Pleasant Hill
August 29, 2006

# re: ASP.NET Cache and Session State Storage

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.

Rick Strahl's Web Log
October 09, 2006

# Why you shouldn't use InProc Session State in ASP.NET - Rick Strahl's Web Log

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.

State Management
December 05, 2006

# ASP.NET Forums - Simultaneous modifying a disconnected dataset in Cache?


State Management
May 15, 2007

# ASP.NET Forums - asp.net Cache and user context


ASP.NET Forums
May 18, 2007

# Caching in a web farm - ASP.NET Forums


ASP.NET Forums
May 18, 2007

# asp.net Cache and user context - ASP.NET Forums


Narendra
July 04, 2007

# re: ASP.NET Cache and Session State Storage

Good Stuff

ASP.NET Forums
July 12, 2007

# Simultaneous modifying a disconnected dataset in Cache? - ASP.NET Forums


Dean Bennett
February 21, 2008

# re: ASP.NET Cache and Session State Storage

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?

Karthic
October 21, 2008

# re: ASP.NET Cache and Session State Storage

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

Sarah Williams
December 03, 2008

# re: ASP.NET Cache and Session State Storage

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!

Abhijeet
January 12, 2009

# re: ASP.NET Cache and Session State Storage

Is there any way to configure IIS to clear cache at the end of every session? What are pros and cons?

Troy (bbqchickenrobot)
February 18, 2009

# re: ASP.NET Cache and Session State Storage

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

dotnetguts
June 11, 2009

# re: ASP.NET Cache and Session State Storage

It was helpful description.

Thanks

eric
August 12, 2009

# re: ASP.NET Cache and Session State Storage

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?

Umar Jamil
August 19, 2009

# re: ASP.NET Cache and Session State Storage

@ 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

Phillip
September 29, 2009

# re: ASP.NET Cache and Session State Storage

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

James
March 16, 2010

# re: ASP.NET Cache and Session State Storage

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

Nav
March 29, 2010

# re: ASP.NET Cache and Session State Storage

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 - 2024