I have an ASP.NET page that calls an HttpHandler
which sets a Session value. Then the page redirects to another page.
That second page calls the same HttpHandler
to get user name from the Session. Problem is sometimes it errors saying the value is null. User name is never null or empty coming from the client.
The pseudo-code looks like this:
public class MyHttpHandler : IHttpHandler: IRequiresSessionState
{
public void ProcessRequest(...){...}
public void SaveUserName(HttpContext context)
{
string userName = context.Request["user_name"];
context.Session["username"] = userName;
}
public void GetUserName(HttpContext context)
{
string userName = "";
if (context.Session["username"] != null)
userName = context.Session["username"];
else
throw new System.Exception("Failed to get user name from Session.");
// returns user name to client...
}
// etc...
}
This post https://stackoverflow.com/questions/1382791/what-should-i-do-if-the-current-asp-net-session-is-null says maybe the code is running before session state is ready, so I tried various things to wait/delay/pause my code, such as Task.Delay
, Thread.Sleep
, calling other Session properties and methods before trying to access username, even having it call a long running SQL query, but nothing worked.
Also, if it's going to fail it usually does so on the very first attempt. In other words, it never fails after a success.
UPDATE: May have found the issue. SaveUserName was being called by a jQuery ajax post in parallel with another jQuery ajax post that's also attempting to update the session object. Could this cause a race condition? Could one post lock the session object and so the other can't update it? It would explain the intermittent nature of the problem. Anyway, we made them sequential. Not sure yet if that's the issue. Will update in a bit once we know...
FINAL UPDATE: Yep, the problem was a race condition between the two ajax calls; each trying to lock the Session object. It was always the first that was successful and only 2% of the time the second was blocked (and the values not set). We moved one to being called earlier in the workflow, so they are no longer in contention.