ReadOnly Session 是可写的

ReadOnly Session is writable

在项目中,我们需要异步地连续执行几个 AJAX 调用,因此下一次调用不必等待 return 之前的调用。即使客户端异步发出调用,由于会话锁定,服务器也会按顺序处理它们。

由于我们不需要在这些调用中修改 Session,我们通过 @Page 指令标记了 AJAX 调用的页面 EnableSessionState="ReadOnly"。它奏效了,通话变得真正异步,不再依赖于彼此的时间安排。但我们发现 - 在该后端代码中,会话尽管被标记为只读,但它是可写的。我们可以为 Session 赋值,并且这些值会持续存在。这是错误还是设计行为?

我想说这种行为是 "by design" 进程中会话状态的陷阱(不幸的是,似乎没有很好的记录)。

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

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

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

进程中的会话状态

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

我想 ASP.NET 团队 可以 在 EnableSessionState 设置为 ReadOnly 时使 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,作为开发人员,您有责任避免更改会话数据。否则,您可能会引入多线程错误。