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:
Here is a page that executes slowly…
We can take these two pages and put them both inside of a frameset so they appear in the same window.
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
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.
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.
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.
Just wondering if out of process session uses locking or not.
Please let me know if u know.
Best Regards,
Ali Kazmi