Pergunta

I have implemented some work which adds values to the Session state inside a Thread. I would like these values to be available outside the Thread (obviously).

The information added to the Session is available outside of the Session without any issues when the Session State mode is "InProc".

When the Session State mode is to "StateServer" however, the behaviour is different. Basically the values set inside the Thread are persisted sometimes and sometimes not. It seems random to me.

Here is code that reproduces the problem.

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
    }

    protected void store_Click(object sender, EventArgs e)
    {
        // Set the session values to default.
        Session["Test1"] = "No";
        Session["Test2"] = "No";

        // Set the Test1 session value in the thread.
        ThreadObject threadObject = new ThreadObject() { Username = Page.User.Identity.Name, SessionState = Session };
        worker = new Thread(new ParameterizedThreadStart(Work));
        worker.Start(threadObject);

        // Set the Test2 session value in this thread just to compare.
        Session["Test2"] = "Yes";
    }

    protected void print_Click(object sender, EventArgs e)
    {
        // Print out the Session values.
        label1.Text = string.Empty;
        label1.Text += "Inside Thread: " + Session["Test1"] + ",  \n";
        label1.Text += "Outside: " + Session["Test2"] + "\n";
    }

    private static Thread worker;

    public static void Work(object threadObject)
    {
        // Retrieve the Session object and set the Test2 value.
        ThreadObject threadObject1 = (ThreadObject)threadObject;
        HttpSessionState currentSession = threadObject1.SessionState;
        currentSession["Test1"] = "Yes";
    }
}

public class ThreadObject
{
    public string Username { get; set; }
    public HttpSessionState SessionState { get; set; }
}

The above code works fine with SessionState mode="InProc", but is random with:

<sessionState mode="StateServer"
  stateConnectionString="tcpip=localhost:42424"
  cookieless="false"
  timeout="20"/>

Any ideas?

EDIT: So as per the comments below the thread needs to finish before the Request (Main Thread) finishes, otherwise anything added to the Session is lost. This is because at the end of the Main Thread the Session is serialized and sent to the data store (Out of Process, or SQL Server).

Foi útil?

Solução

I think this is a timing issue - there's no guarantee that your worker thread will have executed by the time you get to setting your label's values. It takes a few MS to create and launch the tread. By then, the rest of your main thread has probably completed. You can test this by putting debug output and seeing the order in which your code is executed.

If you need to guarantee that the code in your thread executes (which eliminates the need for a thread) - you could use a WaitOne() threading method to have your main thread wait for the worker thread to return. But depending on a value set in a thread to be available in a parallel process is risky.

Additionally - IMHO, I wouldn't use threads in ASP.NET apps - I believe the consensus is that they're a bit dangerous. I've seen app pool crashes because of bad code inside a spawned thread.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top