23
votes

Consider a user making multiple requests at the same time, do I have to lock all code that works with the Session?

If for example I have the following scenario, where in one tab of his browser the user opens a page and in the second he logs out.

Request 1:

if(Session["user"] != null)
    lblName.Text = Session["user"].Name;

Request 2:

if(logout)
   Session["user"] = null;

Is it possible that Request 1 throws a NullPointerException when accessing the Name property? Do i need to lock the code in Request 1, to make sure user still exists after checking for null? Or does ASP.NET deal with this automatically somehow?

4
I would be passing a reference, right? What if Request2 calls Session["user"].Dispose()? Would that affect the user I got out of the Session in Request1? - magnattic
Yes you could be using a disposed object in that case. - Darryl Braaten
Peter Ruderman's answer says it could not be null in Request 1. Two opinions - what's correct? - magnattic
@atticae: It depends on whether you're using in-memory or SQL-based session state. In any case, you should assume that the object could be shared between multiple threads and synchronize access appropriately. - Peter Ruderman
@Darryl Braaten: There is no race condition in Request 1 because ASP.NET uses reader and writer locks on Session. Please read msdn.microsoft.com/en-us/library/aa479041.aspx - Jacob Krall

4 Answers

16
votes

Two requests to an ASP.NET application for the same same session, where the handlers do not use the IReadOnlySessionState marker interface or have the EnableSessionState="ReadOnly" turned on for your pages, will be serialized by the ASP.NET runtime to guarantee consistency of the state. So if you have two pages that are able to write to the session state, they will be accessed serially no matter what the client does on their side.

It's up to your application code to signal to ASP.NET with the afforementioned techniques whether or not a page/handler is going to write to the session state. If you do not, all requests will be serialized and the performance of your web application will suffer.

11
votes

As always, the answer depends on what you mean by "safety." In ASP .NET, each request gets exclusive access to its session state. This means that you don't have to worry about synchronizing access within the scope of a single request. If Session["user"] is non-null, then it will be non-null for the entire duration of the current request. In your example, request 1 will never throw a null reference exception.

5
votes

In ASP.NET, the Session module uses a pair of reader/writer locks per session, so Request 1 will have consistent reads, and Request 2 will block until Request 1 completes.

1
votes

Yes, Session is thread-safe.

There's no need to lock anything. However, the need to check the values never cease to be essential.

Update

Check @Peter Ruderman's answer :)

I will have the decency of not copying it :)