ReadOnly Session是可写的

时间:2015-11-13 16:12:27

标签: asp.net session concurrency webforms session-variables

在out项目中,我们需要异步执行一些AJAX调用,因此下一次调用不必等待之前的返回。即使客户端发出异步调用,服务器也会因会话锁定而按顺序处理它们。

由于我们不需要在这些调用中修改Session,因此我们通过@Page指令标记了AJAX使用EnableSessionState="ReadOnly"调用的页面。它起作用了,呼叫变得真正异步,不再依赖于彼此的时机。但我们发现 - 尽管被标记为ReadOnly,后端代码Session仍然是可写的。我们可以为Session分配值,并且值仍然存在。这是设计中的错误或行为吗?

1 个答案:

答案 0 :(得分:3)

我认为这种行为是一种“按设计”的过程中会话状态(不幸的是,似乎没有很好地记录)。

进程外会话状态(状态服务器或SQL Server)

在每个请求开始时,ASP.NET将会话数据从外部存储加载和反序列化到内存中。每个请求都有自己的数据副本,因此对数据的更改不会影响同一会话中的其他并发请求。

如果EnableSessionState设置为ReadOnly,那么在请求结束时,数据将被丢弃而不是序列化回外部存储。

进程内会话状态

不会发生序列化或反序列化。相反,在内存中有一组会话数据,它们在会话期间存在。同一会话中的每个请求都共享该组数据,并且对其他并发请求立即的数据更改。

我认为只有当EnableSessionState设置为ReadOnly时,ASP.NET团队才能才能读取Session:

this.Session["Customer"] = customer; // Why not throw InvalidOperationException?

但ASP.NET仍然无法检测对象本身的更改:

Customer customer = (Customer)this.Session["Customer"];
customer.Address = address; // ASP.NET can't detect this.

因此,如果将EnableSessionState设置为ReadOnly,作为开发人员的责任是避免更改会话数据。否则,您可能会引入多线程错误。