Session State Management in Project
Migrate In-Proc to Out-Proc State Server
By Chua Wen Ching, January 29, 2007
Overview
There are a lot of reasons why an in-proc session state will lost when a web application is running. To name a few:
- Changes to bin folder, web.config and machine.config
- Changes to other file folders. This is stricter in .NET 2.0 than .NET 1.1.
- Somewhere in the code caused a JIT. Code does not catch the exceptions properly.
- ASP.NET Web Application restarts.
- AppDomain recycles
- Session timeout too short
In order to illustrate the details, I had drawn some visual diagrams to aid my explanations. I did not draw in very detail, but hope it would assists in your understanding.
Problem
Figure 1
By default, an AppDomain will host the ASP.NET Web Application. When you use In-Proc session, basically this session exists within the scope of the web application.
Figure 2
Assuming when you run your web application, you encounter a Just in Time Exception (JIT) and it is not handled properly. The common JIT error is System.NullReferenceException.
Take note, my diagram focuses on web application which restarts because of an unhandled exception. I did not draw on AppDomain.
Figure 3
When your application restarts basically it will lose the session and will generate a new session when the user logins again.
It is possible to happen as when you configure the web application to use In-Proc (or In-Process), it will store the session in the server’s memory.
Solution
I will recommend every developers who want to use Session State Management to consider Out-Process. Honestly speaking every session techniques (In-Process and Out-Process) has its own pros and cons.
Based on my researches, it was recommended to always stick to Out-Process: State Server for all project development. If there is a need to change to In-Process, it will be easier to migrate.
Out-Process session is divided into 2 types:
- State Server (windows service)
- SQL Server (stored in the database as tables)
The major issue with Out-Process is it is very slow compare to In-Process. The reason it is slower than In-Process as there are serialization / de-serialization costs. By passing the .NET Data Types like (string, int) will not cost any overhead. But if you declare a class like (Person, ArrayList) and pass into the session it needs to be serialized. In terms of reliability, Out-Process wins over In-Process.
Figure 4
When you use Out-Process for your session, basically it is stored in either Windows Service or SQL Server.
Figure 5
When you encounter a Just In Time (JIT) Exception, your web application will recycle. However there is no effect to the windows service or SQL Server.
Furthermore you can run your web application in a web server box and the Session State Service in another server.
How-To
Overview
There will be 2 sections on this. First explains the steps by steps and the 2nd one is the enhancement over your existing In-Process codes to Out-Process.
Step by Step
- You need to run the aspnet_state windows service. There are 2 ways to achieve this.
- Go to Start à Run and type “net start aspnet_state” (excludes the double quotes) OR
- Go to Start à Run and type “services.msc”. Then look for ASP.NET State Service and starts it.
New Enhancements
Assuming you has a Framework class library. Within this class library, you have a SessionName class. Below is a snippet of the SessionName.
Existing In-Process SessionName reusable class
public class SessionName : Hashtable
{
public const string SESSION_MODULE = “SESSION_MODULE”;
// other sessions declarations here
}
- Set the SessionState in web.config to support StateServer instead of In-Proc.
Before
<sessionState mode="InProc" stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data source=server;user id=sa;password=r0ti" cookieless="false" timeout="500"/>
After
<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" cookieless="false" timeout="20"/>
- In Framework Class Library, modify the SessionName class file to support serialization.
Before
public class SessionName : Hashtable
{
}
After
[Serializable]
public class SessionName : Hashtable
{
}
- In the same class file SessionName, you have to place support for deserialization. It is not as straightforward as by default SessionName inherits from Hashtable. In Hashtable, the constructor for de-serialization is protected. You need to override this constructor and make it public.
New Changes
[Serializable]
public class SessionName : Hashtable
{
// Existing codes
// Add this code
public SessionName(SerializationInfo info, StreamingContext context)
: base(info, context) { }
}
Conclusion
Hope this document is able to grasp an understanding on these changes for your project. Have a nice day.