I spent some time identifying the behavior of blocking of ASP.NET pages for session object locking, and Patrick’s “Understanding session state modes + FAQ” provides important information:

Q: Does session state have a locking mechanism that serialize the access to state?
A: Session state implements a reader/writer locking mechanism:
- A page (or frame) that has session state write access (e.g. <%@ Page EnableSessionState="True" %>) will hold a writer lock on the session until the request finishes.
- A page (or frame) that has session state read access (e.g. <%@ Page EnableSessionState="ReadOnly" %>) will hold a reader lock on the session until the request finishes.
- Reader lock will block a writer lock; Reader lock will NOT block reader lock; Writer lock will block all reader and writer lock.
- That's why if two frames both have session state write access, one frame has to wait for the other to finish first.

In Patrick’s theory, a reader lock will block a writer lock.  I tried to prove it by test, but failed.

I wrote two ASP.NET pages and one HTML page for the test:

ReaderLock.aspx, EnableSessionState=”ReadOnly”, is expected to hold a reader lock on session.  In Page_Load event, Thread.Sleep 3 seconds, then display the delay duration detail.

<%@ Page Language="C#" EnableSessionState="ReadOnly" %>
<%@ Import Namespace="System.Threading" %>
<script runat="server">
    void Page_Load(object sender, EventArgs e)
    {
        object boo = Session["Boo"];
        DateTime st = DateTime.Now;
        Thread.Sleep(3000);
        Response.Write("ReaderLock.aspx " +
            st.ToString("HH:mm:ss.fff - ") +
            DateTime.Now.ToString("HH:mm:ss.fff"));
        Response.End();
    }
</script>

WriterLock.aspx, EnableSessionState=”True”, should trigger writer lock.  In Page_Load() event, Thread.Sleep 2 seconds, then display the delay duration detail.

<%@ Page Language="C#" EnableSessionState="True" %>
<%@ Import Namespace="System.Threading" %>
<script runat="server">
    void Page_Load(object sender, EventArgs e)
    {
        object boo = Session["Boo"];
        DateTime st = DateTime.Now;
        Thread.Sleep(2000);
        Response.Write("WriterLock.aspx " +
            st.ToString("HH:mm:ss.fff - ") +
            DateTime.Now.ToString("HH:mm:ss.fff"));
        Response.End();
    }
</script>

There are four IFrames in BlockTest.htm, the first one’s src HTML attribute is set to ReaderLock.aspx to make sure it will be loaded first.  Then after 0.1s, 0.2s, 0.3s, the 2nd, 3rd, 4th IFrame’s src will be set to WriterLock.aspx, ReaderLock.aspx and WriterLock.aspx by Javascript setTimeout() method.  This design ensure that the browser will send the 4 requests sequencially, but not simutaneously.

<!DOCTYPE html>
 
<html>
<head>
    <title>Session Lock Test</title>
    <style>
        iframe  { width: 320px; height: 30px; margin: 10px; }
    </style>
    <script type="text/javascript" 
        src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.2.js"> </script>
    <script>
        $(function () {
            setTimeout(function () {
                $("#f1").attr("src", "WriterLock.aspx");
            }, 100);
            setTimeout(function () {
                $("#f2").attr("src", "ReaderLock.aspx");
            }, 200);
            setTimeout(function () {
                $("#f3").attr("src", "WriterLock.aspx");
            }, 300);
        });
    </script>
</head>
<body>
<div><iframe id='f0' src="ReaderLock.aspx"></iframe></div>
<div><iframe id='f1'></iframe></div>
<div><iframe id='f2'></iframe></div>
<div><iframe id='f3'></iframe></div>
</body>
</html>

Here is the test result:

From the start time and end time displayed in each frame, the 2nd WriterLock.aspx really blocked the 3rd and 4th requests (see “Blocking” arrows), so “a writer lock WILL BLOCK reader or writer locks” is proved.  But in the first two frames, ReaderLock.aspx and WriterLock.aspx start at almost the same time, 10:40.35.038 vs 10:40:35.053.  It seems that ReaderLock.aspx(sent in 0.134s) didn’t block the WriterLock.aspx(sent in 0.248s) at all.

I am not sure if I miss anything, but based on the result, “a reader lock will block a writer lock” is proven not true (at least in In-Process session state mode).

Any feedback is welcome.


Comments

Be the first to post a comment

Post a comment