按线程更新的Asp .net会话变量未在Session中反映出来

时间:2013-05-16 14:02:47

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

在我的page1.aspx中,我使用线程从数据库生成报告。

//on button click
Hashtable ht = (Hashtable)Session["ReportParam"];
ReportThreadClass rth = new ReportThreadClass(ht);
Thread thread = new System.Threading.ThreadStart(rth .Run);
thread.Start();

在我的线程类的朗姆酒方法中,我正在更新Hashtable中的值,即我创建了多少页。

//in thread' method        
public virtual void Run()
{      
    int pagecount=0;
    while(done)
    {
        //loading data from DB and generating html pages

        ht["Total_Pages"] = pagecount;
    }
}

在我的Page2.aspx中,我正在阅读会话变量

中的值
Hashtable ht = (Hashtable)Session["ReportParam"];
int TotalPages = (int) ht["Total_Pages"];

当我在InProc模式下运行上面的代码时,每件事情都正常工作我从会话中获取更新的值。 因为每个东西都存储在静态变量中,并且ht被Session引用,所以它会在会话中自动更新(HashTable不需要将它重新分配给会话回来)。

但是当我在状态服务器(OutProc模式)中运行代码时,它需要通过Serializing Hash-table在不同的进程中存储会话数据。

但即使线程完全运行,Total_Pages的值也没有在Page2.aspx中更新。

是否有任何事件或方法被触发以将会话变量中的所有更新存储到State-Server,如果是,那么请告诉我。如果没有,那么请建议我在page2.aspx中获取更新值。

3 个答案:

答案 0 :(得分:1)

我会像这样明确地设置和获取SessionState:

在你的主题中运行

// no complex object like hastable, just a plain value...
Session["pageCount"] = pageCount;

在你的page2.apsx:

var pageCount = (int) Session["pageCount"]??0;

使用out-of-proc会话状态时报表线程未更新其会话值的原因是因为会话无法检测到哈希表具有更改的值,因此它不会使用序列化更新基础storew hastable的版本。当你明确存储一个不可变对象时,它会持续存在一个它的值被改变;

当你的线程完成begtter选项时,会话可能已经消失,就是获取对SqlSessionStateStore的引用并调用SetAndReleaseItemExclusive。最终,您可能希望有一个可以处理您的场景的重载SessionStateProvider。

答案 1 :(得分:0)

效率较低但我可能只是在数据库中ping第2页的页数。

或者为Page1的页面计数创建单独的会话值,同时执行其他所有操作。 (编辑:没关系第二部分,这就是Rene在下面提出的建议)。

答案 2 :(得分:0)

在Out Proc模式中会话在某个事件之后保存,因此如果您的线程正在更新会话变量,那么它将不会保留在存储中。

如果您正在使用Inproc模式,那么会话存储在静态字典中,因此如果您的线程更新它,您将获得任何页面的更新值。

所以你有两个解决这种情况的方法

  1. 使用inProc模式
  2. 使用key维护线程类中的字典,因为会话ID和值是您的哈希表,所以如果page2.aspx想要读取哈希表的值,那么它会将其会话ID传递给方法,并且将返回所需的值。