Measuring Your Usage of Session State
Effective State Management Is One of the Keys to Building Effective Pages
October 30, 2009
CoreCoder
LANGUAGES: C#| VB.NET
ASP.NETVERSIONS: 1.x | 2.0
Measuring Your Usage of Session State
Effective State Management Is One of the Keys to BuildingEffective Pages
By Dino Esposito
If you really want to overhaul your ASP.NET application toincrease performance, you should look at the overall state management policiesbefore you surf the Web for unleashed tips and tricks. Effective statemanagement is certainly not the only factor that influences an application sperformance but it is one of the most important. Simply using a bunch ofoptimization tricks applied to a page that make excessive or bad use of stateinformation doesn t significantly change performance. Fine-tuning the statemanagement is the key factor to fine-tuning the performance of individual pagesand the overall application. In this article, I ll focus on session statemanagement and discuss some of the aspects that are often overlooked bydevelopers. Want an example? Raise your hand if you ve ever distinguished betweenread/write and readonly session state in an ASP.NET application.
Session State Refresher
In ASP.NET, the internal architecture of the session statemanager has been revolutionized, although the same programming interface hasbeen maintained. You feel at home when you meet the familiar Session dictionary,which is just what the Microsoft designers intended. Under the public name ofthe page object, though, a brand new model pulses and lives. Session state isserialized and deserialized to and from a variety of storage media to serveeach request. This is the first big difference from classic ASP, where sessionstate had just one possible location: the Web server s memory. In ASP.NET, thesession state can be stored in the Web server s memory (default option), the memoryof an external process, or a SQL temporary or persistent table.
Clearly, cross-process serialization and deserializationof the session data has a cost measured in an additional 15% if you use thememory of an external process (the state server). If you opt for a SQL Server,the extra cost raises up to 25% (at a minimum). It is worth noting that extracosts apply to each and every request that doesn t explicitly turn off sessionstate. Note also that the type of data stored in a session influences theserialization process. Simple types such as strings, numbers, dates, and arraysof simple types are processed faster. For custom types and complex classes suchas the DataSet, ASP.NET resorts to the binary formatter, which requires moretime and memory space. If complex types are used, the extra cost per requestcan go up in a measure that depends on actual types used. (Be aware that in the.NET Framework 1.x the DataSet serializes in XML, which can make the requiredtime and space for out-of-process solutions soon unacceptable.)
When setting up session state, you can choose one of thepossible working modes: InProc, StateServer, and SqlServer. The first option,InProc, is the default and the fastest. It makes session state work mostly(but not exactly) like in classic ASP. By assigning data to an executable namedaspnet_state.exe, StateServer keeps your data safe in case of IIS failures. Theexecutable uses .NET Remoting through a customizable port to exchange data withthe ASP.NET application. Finally, SqlServer is the database option that isideal when you need extreme robustness, as well as data persistence. Sessiondata is stored in a made-to-measure database table that may even survive SQLServer crashes. (To be precise, in ASP.NET 1.1 you can choose between temporaryand persistent tables.) When in SqlServer mode you can store data on anyconnected machine, as long as the machine runs SQL Server 7.0 or newer. Thedatabase name is ASPState and scripts are available to create all necessarytables. Expired sessions are deleted using a job that requires the SQL ServerAgent to be up and running.
Overview of the Session State Architecture
In ASP.NET, session state management is governed by asystem-provided HTTP module named SessionStateModule. The module filters eachand every incoming request that doesn t disable session state. It firstdetermines the required working mode and instantiates the proper state providercomponent. The state provider is the internal component that actually retrievesthe state associated with a particular session ID. To guarantee transparency,and enable the HTTP module to call into any supported component, the stateprovider implements the IStateClientManager interface. This interface is notintended for use by developers, and as such is not documented. Suffice it tosay that IStateClientManager exposes a bunch of methods by means of which theHTTP module retrieves the so-called session state item a single object thatcontains all the name/value pairs for the specified session ID.
The HTTP module works by hooking the systemBeginAcquireState and CompleteAcquireState events. Handling the former, it asksthe state provider to retrieve the session state item. Handling the latter, itfills the Session dictionary with the pairs read from the session state item.Bear in mind that the real object behind the public name of Session (a propertyon the HTTP context) is a collection of type HttpSessionState.
At the end of the request, the current content of thedictionary, as modified by the page, is flushed back to the state provider sstorage.
One thing that ASP.NET session state has in common withclassic ASP session state is the serialized access to the state. In otherwords, two different requests within the same session will never executeconcurrently. Admittedly, this may not be a relevant problem unless you haveframesets or know that your users tend to open multiple browser windows. Morein general, serialized access to session state poses a potential performanceproblem if one of the involved pages or frames starts a lengthy task. If thisis the case, the risk is that others will wait until the first one completes.Figure 1 shows the internal serialization mechanism to ensure that each requestsees up-to-date and consistent data.
Figure 1: Serialized access to thesession state.
Take Advantage of Smart Code
Serialized access is a good thing provided that youreally need it. And when is it that you can t do without serialized access?Concurrent access to a shared block of data (in the end, this is what sessionstate is all about) should be prohibited as long as one of the accessors hasthe permission to modify it. That s what happens with ASP.NET session state,and that can be slightly optimized.
Too many developers often overlook the fact that ASP.NETsession state can be disabled or configured to request read-only access. If aparticular page doesn t touch session state, then there s no reason for leavingit turned on. You disable session state on individual pages by using theEnableSessionState attribute on the @Page directive:
<%@ Page EnableSessionState="false" %>
To understand the scope of this little change, think of apage used to download an image read from a database or dynamically created ormodified page. Most of the times, a similar page doesn t need to perform anyaccess to the session state. Nonetheless, session state is retrieved andattached to the Session property unless you mark the page as shown above. Ifthe page runs in a Web Farm application that employs SQL Server session state,you perform unnecessary access to the database each and every time the page isrequested. Implementing this trick doesn t even require you to touch thecode-behind class.
Likewise, a page that only reads from the session stateshould be properly configured so that the ASP.NET runtime doesn t pose any lockon the session state and allows concurrent reads:
<%@ Page EnableSessionState="readonly" %>
To feel the difference, consider the page shown in Figure2. It contains three buttons, the first of which simply adds a value to thesession state. Run the page and click this button. Next, open a second windowby pressing Ctrl-N in Internet Explorer. Resize the two browser windows and laythem out as shown in Figure 3. When done, click to block the page on one of thewindows and try to read from the other. The second page won t be able to readuntil the first has completed its tasks simply waiting for six seconds.
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Threading" %>
</p><p>void Page_Load(object sender, EventArgs e) {}</p><p>void OnSave(object sender, EventArgs e) {</p><p> Session["Hello"] = "world"; </p><p>}</p><p>void OnBlock(object sender, EventArgs e) {</p><p> Thread.Sleep(6000); </p><p>}</p><p>void OnTryToRead(object sender, EventArgs e) {</p><p> Response.Write(Session["Hello"].ToString());</p><p>}</p><p>
Session ID is: "Modify SessionState" /> "Block the Page"/> "Try to read" />Figure 2: Add a valueto the session state.
Figure 3: No reads are allowed untilthe previous request has completed. If you modify the page to use readonly session state(assuming there s something to read in the session state), you ll see thatreading is immediate, no matter if another page request is ongoing. Be awarethat session state is read/write by default. Furthermore, no exception isthrown if you attempt to write to a session from within a page marked forreadonly access; the code simply has no effect. ASP.NET provides some very cool, and very smart features.But you need to be smart also; take advantage of these features and the benefitwill show in your code. The value assigned to the EnableSessionState attribute isprocessed by the ASP.NET runtime when creating the dynamic class to render thepage. In particular, an interface is added to the page declaration to indicatethe type of support requested for the session. A page named default.aspx withfull access to the session state looks like this to the HTTP runtime: public default_aspx : Page, IRequiresSessionState{ :} IRequiresSessionState is a marker interface, meaning thatit has no methods to implement. The interface specifies that the target pagehas read and write access to session-state values. Likewise, readonly access ischaracterized by another marker interface: the IReadOnlySessionState interface.
Conclusion
Although stronger and more reliable than in classic ASP,session state remains a delicate subsystem of any Web application. Optimizingsession state is one of the major points in the process of building effectiveand high-performance applications. Session state should be used because it is aform of data caching without most of the drawbacks of classic ASP. However, beforewarned: To avoid taxing the Web server s memory or communication betweeninternal components of the ASP.NET puzzle, it shouldn t be overused.
As a final note, keep in mind that in case of emptysession state, a brand new session ID is generated per each request and thesession state is not persisted to the state provider. This is what happensunless you define a Session_Start event handler. As a result, do not define anempty and useless Session_Start handler in your global.asax. If you do, yoursystem will always experience per-request serialization/deserialization ofempty data structures the best possible definition of useless code.
The sample code accompanyingthis article is available for download.
Dino Esposito is aWintellect trainer and consultant who specializes in ASP.NET and ADO.NET.Author of Programming Microsoft ASP.NETand Introducing ASP.NET 2.0, both fromMicrosoft Press, Dino also helped several companies architect and buildeffective products for ASP.NET developers. Dino is the cofounder of http://www.DotNet2TheMax.com, apopular portal for .NET programmers. Write to him at mailto:[email protected] or jointhe blog at http://weblogs.asp.net/despos.
About the Author
You May Also Like