1

我编写了托管在 Azure 中的 MVC 3 应用程序。我正在使用会话变量来存储我长期运行的进程之一的 http 调用之间的更新状态信息。然后使用它来更新进度条。这些值可以很快改变。

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

我现在正在更改内容以直接使用缓存变量,这似乎到目前为止有效。

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

例如,我设置可能在一个控制器 ActionResult 中启动会话变量

Session["OPERATION_PROGRESS"] = 0;

然后我得到一个会话的句柄,比如

HttpSessionStateBase session = Session;

并将其传递给我的长期运行过程,例如

LongRunningProcess.Go(session);

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

passedSession["OPERATION_PROGRESS"]=10;

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

4

1 回答 1

2

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

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

仍然有一个对象可供您交谈(这就是为什么您的长时间运行的过程仍然有效的原因),但是对该对象的任何更改都不会发送到持久层(这就是后续请求不会获取这些更改的原因)。

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

如果您要使用 azure 表存储,则对这个系统的改进是使用当前时间滴答作为分区键,并使用另一个唯一 ID 作为行键。通过这种方式,很容易找到在表中比应有的时间更长的行并将其清除。

于 2012-05-03T01:31:09.613 回答