Session State Uses a Reader-Writer Lock

Sunday, May 21, 2006

To prevent two pages from modifying in-process Session variables at the same time, the ASP.NET runtime uses a lock. When a request arrives for a page that reads and writes Session variables, the runtime acquires a writer lock. The writer lock will block other pages in the same Session who might write to the same session variables.

It’s easy to see the runtime implications of the lock when using two pages in a frameset. Here is a page that executes quickly:

<%@ Page Language="C#" %>

<script runat="server">

  protected void Page_Load(object sender, EventArgs e)
  {
    Response.Write(
DateTime.Now.ToLongTimeString());
  }
</script>

<
form runat="server">
  <asp:button runat="server" text="refresh" />
</
form>

Here is a page that executes slowly…

<%@ Page Language="C#" %>

<script runat="server">

  protected void Page_Load(object sender, EventArgs e)
  {
    System.Threading.Thread.Sleep(5000);
    Response.Write(DateTime.Now.ToLongTimeString());
  }
</script>

<
form id="Form1" runat="server">
  <asp:button runat="server" text="refresh" />
</
form>

We can take these two pages and put them both inside of a frameset so they appear in the same window.

<%@ Page Language="C#" %>

<frameset rows="50%, 50%">
  <frame src="quickpage.aspx" />
  <frame src="slowpage.aspx" />
</
frameset>

If we click the button on the slow page, then quickly click the button on the quick page, we’ll see the quick page doesn’t finish processing until the slow page ends. The slow page has to release a lock before the quick page can begin processing.

If this behavior causes a problem, one solution is to use the EnableSessionState attribute in the @ Page directive and tell the runtime how the page intends to use Session variables. If the Page doesn’t need Session state set EnableSessionState=”false” and avoid locking altogether. If the Page only reads Session variables use EnableSessionState=”ReadOnly” (although note that the runtime doesn’t throw an exception if the page actually does write to a Session variable – the write seems to happen just fine).


Comments
Sergio Monday, May 22, 2006
Well, your post made it sound like ASP.NET can only handle a single request at a time unless you change that directive in all your pages (if you don't use session vars.)
Do you think part of the behavior you experienced was due to using a debugger or the internal web server (cassini) ?
Since we cannot see you writing or even reading from session vars in your above examples, it doesn't make a lot of sense why ASP.NET would wait for slowpage.aspx to end before returning quickpage.aspx in a production environment.
scott Monday, May 22, 2006
Hi Sergio:

ASP.NET handles multiple requests, but only a single request can have write access to a given inproc Session at one time.

The quick page would have to wait for the slow page to finish processing because the quick page has to wait for the slow page to release the writer lock. Both pages are trying to get to the same user Session.

If quick page and slow page were requested from two different user sessions, there would be no contention and both pages would return as quickly as possible.

This behavior is the same under Cassini and IIS, and without any side effects from a debugger.

The reason this behavior happens without even touching a Session variable is because the default setting is EnableSessionState="true".

The SessionStateModule (HttpModule) inpsects this setting early in the request and assumes the page will want to read and write session variables. It loads session state using using a session state provider (in the inproc case, a class called InProcSessionStateStore). This class takes the lock.
Simone Busoli Friday, June 16, 2006
Hi Scott, it sounded really strange to me when I read about the behavior you described in your post, and immediately tested it. In fact, although your description could make sense, what I'm getting is that the quick page posts back immediately, even in the slow page is still processing.

The reason why it looked weird to me is that I have been working on the InProcessSessionStore and I'm pretty sure it doesn't lock any resource until you ask for it.

If you reflector it you can see that the reader-writer locks occur only when GetItem and GetItemExcusive methods are called, while the session http module doesn't get locks; it would hurt performances really bad.
gravatar Ali Kazmi Monday, October 25, 2010
Hi,

Just wondering if out of process session uses locking or not.

Please let me know if u know.

Best Regards,
Ali Kazmi
Comments are now closed.
by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!