我编写了一个托管在 Azure 中的 MVC 3 应用程序。我正在使用 session 变量来存储长期运行的进程之一上的 http 调用之间的更新状态信息。然后用它来更新进度条。这些值可能会快速变化。
当使用 InProc session 提供程序时,这一切都非常有效。但是,每当我更改为使用 Azure 缓存 session 提供程序时, session 变量都不会从长时间运行的进程中更新。
我现在正在更改内容以直接使用缓存变量,到目前为止这似乎有效。
为什么下面的方法在缓存中使用Session时不起作用,但在InProc中却可以?
例如,我设置可能会在一个 Controller ActionResult 中启动一个 session 变量
Session["OPERATION_PROGRESS"] = 0;
然后我就可以处理 session 了
HttpSessionStateBase session = Session;
并将其传递给我长时间运行的进程,例如
LongRunningProcess.Go(session);
然后,在 LongRunningProcess 方法中,它将在使用传递的 session 对象执行任务时更新 session 变量。
passedSession["OPERATION_PROGRESS"]=10;
Web 客户端调用一个进度页面,该页面将 session 变量值传回以更新进度条。
最佳答案
根据我最近阅读的有关 session 提供程序的内容,我怀疑正在发生的情况是,在初始化长时间运行的请求完成后, session 提供程序释放其对 session 信息的锁定,从而有效地断开连接。来自 MSDN :
At the end of a request, if the session-state values have been modified, the SessionStateModule instance calls the SessionStateStoreProviderBase.SetAndReleaseItemExclusive method to write the updated values to the session-state store.
仍然有一个对象可供您交谈(这就是为什么您的长时间运行的进程仍然有效),但是对该对象的任何更改都不会发送到持久层(这就是为什么后续请求不会获取这些更改)更改)。
我在类似情况下所做的就是在请求开始时生成一个请求 ID,并在 azure 表中创建一行,并将其作为分区键(但您可以使用您喜欢的任何存储),传递此 ID进入长时间运行的进程,并将此 id 返回给客户端。长时间运行的进程仅更新表中的这一行。所有后续的进度请求都会通过此请求 ID 传递,查找它很简单。为了防止表变得太大,在发现过程完成的请求时,它会删除该行。
如果您要使用 Azure 表存储,则对该系统的改进是使用当前时间(以刻度为单位)作为分区键,并使用另一个唯一 ID 作为行键。这样就可以很容易地找到表中存在时间超过应有时间的行并将其清除。
关于asp.net-mvc-3 - 使用 Azure 缓存时 session 变量未更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10414014/