3

我们的 ASP.NET 应用程序在同一个会话中并行发送多个 Ajax 请求。HttpSessionState我们还在其中一些请求期间读/写。我想要的是所有并发请求出于性能原因并行执行。我得到的是它们由 ASP.NET 序列化。我尝试了配置enableSessionState="ReadOnly",但这破坏了我们的表单身份验证。

有没有办法在一个会话中同时获得会话状态和并发?我需要使用自定义SessionState还是Provider?有这方面的样本吗?

PS 在访问 SessionState 时,我并不担心线程安全——我可以通过编程方式做到这一点。

4

1 回答 1

2

从 MSDN(链接):

但是,如果对同一个会话发出两个并发请求(通过使用相同的 SessionID 值),则第一个请求将获得对会话信息的独占访问权。第二个请求仅在第一个请求完成后执行。

因此,至少对于那些需要对 Session 进行写访问的 AJAX 调用,您对默认提供程序不走运。

不确定您是否可以使用自定义提供程序解决此问题。

可以通过ASP.NET_SessionIdHttpModule. 请参阅我对这个问题的回答

编辑:为了使这个答案更加独立,我添加了一个稍微修改的版本HttpModule和一些讨论(进一步向下)。下面是可用于防止 Session 状态序列化 Ajax 调用的模块代码:

using System; 
using System.Web; 

namespace TestModule 
{ 
    public class TestPreventCookie : IHttpModule 
    { 
        public void Dispose() 
        { 
        } 
        public void Init(HttpApplication application) 
        { 
            application.BeginRequest += 
                (new EventHandler(this.Application_BeginRequest)); 
            application.PostAcquireRequestState += 
                (new EventHandler(this.Application_PostAcquireRequestState)); 

        } 
        private void Application_BeginRequest(Object source, EventArgs e) 
        { 
            //prevent session cookie from reaching the service 
            HttpApplication application = (HttpApplication)source; 
            HttpContext context = application.Context; 
            if (BlockCookie(context)) 
            { 
                context.Request.Cookies.Remove("ASP.NET_SessionId"); 
            } 
        } 
        private void Application_PostAcquireRequestState(Object source, EventArgs e) 
        { 
            HttpApplication application = (HttpApplication)source; 
            HttpContext context = application.Context; 
            if (BlockCookie(context)) 
            { 
                var s = context.Session; 
                if (s != null) 
                    s.Abandon(); 
            } 
        }
        private bool BlockCookie(HttpContext context)
        {
            // put code here that determines if the session cookie should be blocked
            // this could be based on the path of the current request for instance
            // only block the cookie when you *know* that access to the Session is not needed
        }
    } 
}

这个模块背后的想法是,使用基于项目要求的一些标准,我们ASP.NET_SessionId从当前上下文中删除 cookie(注意,我们不会在客户端将其过期)。

这意味着在请求管道中,服务器将创建一个新会话。为了防止这个新创建的会话破坏ASP.NET_SessionId客户端上现有的 cookie,我们在它创建后立即放弃它。

最终结果是每个被模块“拦截”的请求都会像没有会话一样执行。

于 2012-08-29T11:48:33.433 回答