会话模式“ServerState”不能正确处理线程中的Session

时间:2013-02-25 05:33:44

标签: c# asp.net session stateserver session-state-server

我已经实现了一些工作,它为Thread内部的Session状态添加了值。我希望这些值在Thread之外可用(显然)。

当会话状态模式为“InProc”时,添加到会话的信息在会话之外可用,没有任何问题。

当会话状态模式为“StateServer”时,行为是不同的。基本上,线程中设置的值是持久的有时,有时不是。对我来说似乎是随机的。

以下是重现问题的代码。

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; }
}

以上代码适用于SessionState mode =“InProc”,但随机使用:

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

有什么想法吗?

编辑:所以根据下面的评论,线程需要在Request(主线程)完成之前完成,否则添加到Session的任何内容都将丢失。这是因为在主线程结束时,会话被序列化并发送到数据存储(进程外或SQL Server)。

1 个答案:

答案 0 :(得分:1)

我认为这是一个时间问题 - 当您设置标签的值时,无法保证您的工作线程已经执行。需要几个MS才能创建并启动胎面。到那时,主线程的其余部分可能已经完成了。您可以通过调试输出并查看代码执行的顺序来测试它。

如果您需要保证线程中的代码执行(这消除了对线程的需要) - 您可以使用WaitOne()线程方法让主线程等待工作线程返回。但是,根据在并行进程中可用的线程中设置的值是有风险的。

此外 - 恕我直言,我不会在ASP.NET应用程序中使用线程 - 我相信共识是​​它们有点危险。我发现应用程序池崩溃是因为生成的线程中存在错误的代码。