Asp.net从异步线程更新会话值

时间:2016-04-18 20:17:38

标签: c# asp.net asp.net-mvc multithreading session

在我的ASP.Net MVC应用程序中,我需要使用线程初始化一个长时间运行的函数。初始化线程后,将返回响应并加载页面。在此页面中,每隔30秒触发一次ajax请求,以从存储在会话中的值检查长时间运行的函数的状态(此值从子线程内更新)。 出现问题是因为一旦返回响应,HttpContext.Current就变为null,即使这个HttpContext.Current从父线程传递给子线程,session属性也为null。所以,我不能从子线程设置会话值。此外,由于我们正在实现具有非粘性会话的负载平衡环境,因此无法使用应用程序缓存。 我可以使用父调用的sessionId获取子线程中的会话数据并更新吗?或者可以通过其他方式完成吗? 任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

在这种情况下,我会创建一个静态字典,哈希表等(让我们为了参数而说字典),并将密钥作为会话ID。将该字典存储在您的页面和长时间运行的函数(可能在静态类中?)可访问的某个地方。当你的页面/应用程序/任何东西启动长时间运行的功能时,让它为字典添加一个条目(以会话ID作为键)。它可以检查每个回调的字典条目的值。长时间运行的函数会在调用时接收会话ID,完成后它可以使用它来访问字典中的条目。

这里有一个问题 - 如果你在完成它之后不清楚它,那么字典可能会变得非常大。我建议让页面在检查后删除字典中的条目,并看到长时间运行的功能已经完成。我也可能(作为额外的安全机制)在Global.asax文件中的会话结束事件中添加代码,以检查该字典是否有一个条目,该条目的会话ID已经结束,如果所以,删除它。

答案 1 :(得分:0)

由于您使用的是loadbalancer,因此只有适当的数据存储才能成为数据库(或任何类型的内存缓存)

例如为: 当用户请求页面时:

  1. 将待处理记录添加到数据库
  2. 启动线程进行后台计算(记录id是参数)
  3. 将此记录ID存储到会话
  4. 线程完成时:

    1. 更新数据库记录
    2. 当客户回访时,您可以轻松跟踪您的长期运行功能是否已完成。

      你不应该触及会话本身。如果您找到更新会话的方法(例如,使用mssql会话阶段),但碰巧在下一个客户请求中更新会话,您的更改将会丢失。