使用Azure缓存时,会话变量不会更新

时间:2012-05-02 12:43:18

标签: asp.net-mvc-3 session azure session-variables azure-caching

我编写了一个在Azure中托管的MVC 3应用程序。我正在使用Session变量在我长时间运行的进程之一的http调用之间存储更新状态信息。然后,这用于更新进度条。价值观可以很快改变。

使用InProc会话提供程序时,这一切都很有效。但是,每当我更改为使用Azure缓存会话提供程序时,会话变量都不会从长时间运行的进程中更新。

我现在正在改变直接使用Cache变量的东西,这似乎到目前为止。

为什么在缓存中使用Session时,以下方法不起作用,但是InProc很好?

例如,我设置可能会在一个控制器ActionResult

中启动一个会话变量
Session["OPERATION_PROGRESS"] = 0;

然后我会像

那样处理会话
HttpSessionStateBase session = Session;

并将其传递给我的长时间运行过程,如

LongRunningProcess.Go(session);

然后,在LongRunningProcess方法中,它将使用传递的会话对象更新会话变量。

passedSession["OPERATION_PROGRESS"]=10;

webs客户端调用一个进度页面,该页面将会话变量值传递回来更新进度条。

1 个答案:

答案 0 :(得分:2)

根据我最近读到的有关会话提供程序的内容,我怀疑发生的情况是,在初始化长时间运行请求的请求完成后,会话提供程序释放其对会话信息的锁定,从而有效地断开连接。来自MSDN

  

在请求结束时,如果会话状态值已经存在   修改后,SessionStateModule实例调用   SessionStateStoreProviderBase.SetAndReleaseItemExclusive方法   将更新的值写入会话状态存储。

还有一个对象可以与你交谈(这就是为什么你的长时间运行过程仍然有效),但是没有对该对象的更改被发送到持久层(这就是为什么后续请求不会接收那些变化)。

我在类似情况下所做的是在请求开始时生成请求ID并在azure表中创建一行,并将其作为分区键(但您可以使用任何您喜欢的存储),传递此ID进入长时间运行的过程并将此id返回给客户端。长时间运行的进程只更新表中的这一行。所有后续的进度请求都会在此请求ID中传递,查找它很简单。要阻止表变得太大,请在发现进程完成的请求上删除该行。

如果要使用azure表存储,对此系统的改进是使用刻度中的当前时间作为分区键,将另一个唯一ID用作行键。通过这种方式,可以很容易地找到表中已存在的行,并将其清除掉。