views:

496

answers:

0

Hello

We have an strange problem with accessing to session variables concurrently. The microsoft documentation says that if two request are made for the same session (using the same sessionId), the second request execute only after the first request has finished. http://msdn.microsoft.com/en-us/library/ms178581.aspx

In our cases the behauvior of session is different and we don't know the reason of it different behaviour. If we have two requests with the same sessionId the two request are processed simultaneously, and modify simultaneously the session variable, (as I write above microsoft documentation said that the second request is not processed until the first finish). We don't understand why the two request are processed at the same time, and obviously if two request modified the session variables at the same time, the result of the session variables isn't correct.

We have developed this small code to reproduce the problem, that write log on a file to observe how the two request are executed simultaneusly. To reproduce the problem open the test page in two tabs of your browse and click the button of the first tab and then of the click the button of the second tab before the first finish.

default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default4.aspx.cs" Inherits="Default4" EnableSessionState="True" %>

Untitled Page

default.aspx.cs

protected void Button1_Click(object sender, EventArgs e)
{
    try
    {
        m_file = File.AppendText(Request.MapPath(Request.ApplicationPath) + "\\request_one.txt");
    }
    catch
    {
        m_file = File.AppendText(Request.MapPath(Request.ApplicationPath) + "\\request_two.txt");
    }
    m_file.WriteLine("SessionID: " + Session.SessionID);

    m_file.WriteLine(DateTime.Now.ToString() + " Thread " + GetCurrentThreadIdAsString() + ". I sleep");

    System.Threading.Thread.Sleep(2000);

    m_file.WriteLine(DateTime.Now.ToString() + " Thread " + GetCurrentThreadIdAsString() + ". I wake up");

    Label1.Text = "Session value : " + Test().ToString() + " Thread id " + System.Threading.Thread.CurrentThread.GetHashCode();


    m_file.Close();
}

public int Test()
{
    m_file.WriteLine(DateTime.Now.ToString() + " Thread " + GetCurrentThreadIdAsString() + ". I check if Session variable 'SessionTest' is null");

        if (System.Web.HttpContext.Current.Session["SessionTest"] == null)
        {
            m_file.WriteLine(DateTime.Now.ToString() + " Thread " + GetCurrentThreadIdAsString() + ". 'SessionTest' is null");

            m_file.WriteLine(DateTime.Now.ToString() + " Thread " + GetCurrentThreadIdAsString() + ". I start to calculate");

            int i = 1;

            i = i * 2;
            i = i * 2;
            i = i * 2;

            m_file.WriteLine(DateTime.Now.ToString() + " Thread " + GetCurrentThreadIdAsString() + ". I finish calculate, I sleep");

            System.Threading.Thread.Sleep(1000);

            m_file.WriteLine(DateTime.Now.ToString() + " Thread " + GetCurrentThreadIdAsString() + ". I modify Session variable 'SessionTest'.");

            System.Web.HttpContext.Current.Session["SessionTest"] = i.ToString();

            m_file.WriteLine(DateTime.Now.ToString() + " Thread " + GetCurrentThreadIdAsString() + ". Session variable 'SessionTest' modified.");
        }
        else
        {
            m_file.WriteLine("Thread " + GetCurrentThreadIdAsString() + ". I check if Session variable 'SessionTest' is not null");
            System.Web.HttpContext.Current.Session["SessionTest"] = (Int32.Parse(System.Web.HttpContext.Current.Session["SessionTest"].ToString()) * 2);
        }

        m_file.WriteLine("Thread " + GetCurrentThreadIdAsString() + ". Return value " + System.Web.HttpContext.Current.Session["SessionTest"].ToString());
        return Int32.Parse(System.Web.HttpContext.Current.Session["SessionTest"].ToString());
}

public string GetCurrentThreadIdAsString()
{
    return System.Threading.Thread.CurrentThread.GetHashCode().ToString();
}

Debugging the code we have observed that the two request are executing simultaneously and It seems that they get different instance of session each request, because after the first request assing value to SessionVariable SessionTes,t for the second request when assing the value to sesison variable SessionTest with a quick watch we observe that the value of the variable it stills null, when the first request has modified it.

In all websites we look say that only one request can access to the session variables when there are writing operations, the request acquire a lock and it doesn't release until has finished, but in our case the two request access simultaneously to the session variables.

Looking at the log file generated you can observe how the two request are process simultaneously

Request one:

SessionID: 1gwknr55uts1xu55mfgqp1fz 04/08/2009 12:33:57 Thread 11. I sleep

04/08/2009 12:33:59 Thread 11. I wake up

04/08/2009 12:33:59 Thread 11. I check if Session variable 'SessionTest' is null

04/08/2009 12:33:59 Thread 11. 'SessionTest' is null

04/08/2009 12:33:59 Thread 11. I start to calculate

04/08/2009 12:33:59 Thread 11. I finish calculate, I sleep

04/08/2009 12:34:00 Thread 11. I modify Session variable 'SessionTest'.

04/08/2009 12:34:00 Thread 11. Session variable 'SessionTest' modified.

Thread 11. Return value 8

Request 2:

SessionID: 1gwknr55uts1xu55mfgqp1fz

04/08/2009 12:33:59 Thread 13. I sleep

04/08/2009 12:34:01 Thread 13. I wake up

04/08/2009 12:34:01 Thread 13. I check if Session variable 'SessionTest' is null

04/08/2009 12:34:01 Thread 13. 'SessionTest' is null

04/08/2009 12:34:01 Thread 13. I start to calculate

04/08/2009 12:34:01 Thread 13. I finish calculate, I sleep

04/08/2009 12:34:02 Thread 13. I modify Session variable 'SessionTest'.

04/08/2009 12:34:02 Thread 13. Session variable 'SessionTest' modified.

Thread 13. Return value 8

For more information we use Session Mode "inProcess", we have try it with "State server" mode and the behaviour is the same. We have test this problem with three machines, and the behaviour was the same, two machines with windows xp professional and another with windows 2003 server.

Here you can find the code to reproduce the problem rapidshare.com/files/263575022/SessionTest.rar.html , the time session is of 1 minute.

Thanks in advance for your help