Synchronizing Access to a member of the ASP.NET se

2019-02-18 03:37发布

问题:

I'm building a Javascript application and eash user has an individual UserSession. The application makes a bunch of Ajax calls. Each Ajax call needs access to a single UserSession object for the user.

  1. Each Ajax call needs a UserSession object.

  2. Data in the UserSession object is unique to each user.

Originally, during each Ajax call I would create a new UserSession object and it's data members were stored in the ASP.NET Session. However, I found that the UserSession object was being instantiated a lot. To minimize the construction of the UserSession object, I wrapped it in a Singleton pattern and sychronized access to it.

I believe that the synchronization is happening application wide, however I only need it to happen per user. I saw a post here that says the ASP.NET cache is synchronized, however the time between creating the object and inserting it into the cache another Thread could start construction it's another object and insert it into the cache.

Here is the way I'm currently synchronizing access to the object. Is there a better way than using "lock"... should be be locking on the HttpContext.Session object?

private static object SessionLock = new object();

public static WebSession GetSession
{
    get
    {
        lock (SessionLock)
        {
            try
            {
                var context = HttpContext.Current;
                WebSession result = null;

                if (context.Session["MySession"] == null)
                {
                    result = new WebSession(context);
                    context.Session["MySession"] = result;
                }
                else
                {
                    result = (WebSession)context.Session["MySession"];
                }

                return result;
            }
            catch (Exception ex)
            {
                ex.Handle();
                return null;
            }
        }
    }
}

回答1:

You don't need to lock Session state access.

The physical values of a session state are locked for the time needed to complete a request. The lock is managed internally by the HTTP module and used to synchronize access to the session state.

http://msdn.microsoft.com/en-us/library/aa479041.aspx



回答2:

In general, you don't need this kind of code for asp.net session access, since access to each session is limited to a single user. The only reason I can think of for locking access to your session object is if you expect to have multiple simultaneous ajax requests, and even so, I think asp.net would synchronize the access for you.

If you do decide to lock, you only really need to do it if your session object is null:

if (context.Session["MySession"] == null) {
  lock(SessionLock) {
    if (context.Session["MySession"] == null) {
      context.Session["MySession"] = new WebSession(context);  // try-catch block removed for clarity (and my laziness)
    }
  }
}
return (WebSession)context.Session["MySession"];