之前遇到一个问题。
于是做了以下实验:
页面加载后,提交一个Ajax请求(暂称为ajax1),请求的线程在服务器上被睡眠10秒钟。
点击页面上一个button,触发另一个Ajax请求(ajax2)。当没有使用session,在服务器未处理完ajax1的请求时,服务器依然可以处理ajax2的请求。
但是,当使用了session,在服务器未处理完ajax1的请求时,服务器不能处理ajax2的请求。必须等到ajax1处理完成后,才能处理ajax2的请求。使用session的代码很简单,Session.Add("user", "aaa");求教牛人,如何在使用了session后,当ajax1未处理完成时,依然可以处理ajax2的请求?

解决方案 »

  1.   

    这个问题,让我很头大。
    ajax不是发送的异步请求吗?
    为什么,使用了session后,就变成同步的了?
      

  2.   

    代码贴出来
    http://www.zainanbao.com
      

  3.   

    我想的是Ajax1和Ajax2这两个请求是不是都用到了session呢了代码中,要是都用到了,可能session不允许同时进行访问,所以导致了你现在的情况。
      

  4.   


            protected void Page_Load(object sender, EventArgs e)
            {
                //使用session的代码
                Session.Add("user", "aaa");
                switch (Request.QueryString["action"])
                {
                    case "ajax1":
                        Thread.Sleep(8000);
                        Response.Clear();
                        Response.Write("alert('ajax1');");
                        Response.End();
                        break;
                    case "ajax2":
                        Response.Clear();
                        Response.Write("alert('ajax2');");
                        Response.End();
                        break;
                }
            }
    这是处理两个ajax请求的代码。
      

  5.   


    开始,我也怀疑这种情况。
    然后,我将Session.Add("user", "aaa")代码片段,放置另一个页面(Login.aspx)中,然后再跳转到测试页面(Default.aspx)。
    代码如下:        protected void Button1_Click(object sender, EventArgs e)
            {
                Session.Add("user", "aaa");            Response.Redirect("Default.aspx");
            }Default.aspx是处理两个ajax请求的页面。
    这样,两个ajax请求,不再访问session代码了。
    但是,一样会出现我所叙述的问题。
      

  6.   

    默认情况下,Session 不是同步的
      

  7.   

    你说的ajax 是指什么 xhr  (xmlhttprequest) ?如果是的话, 在open 的时候 你设置异步请求了么  就是第三个参数你贴服务器的代码 看不出什么 ,让你贴的是ajax 部分的代码
      

  8.   


    function myXmlHttp(){}myXmlHttp.prototype.sendXmlHttp=
        function(url,data,fun){
            var xmlHttp;        if (window.ActiveXObject) {
                xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
            else if (window.XMLHttpRequest) {
                xmlHttp = new XMLHttpRequest();
            }        xmlHttp.open("POST", url, true);        xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");        xmlHttp.onreadystatechange = function() {
                if (xmlHttp.readyState == 4) {
                    if (xmlHttp.status == 200) {
                        if (xmlHttp.responsetext != "") {
                            if(fun !=""&&fun !=undefined)
                            {
                                fun(xmlHttp.responsetext);
                            }
                        }
                    }
                }
            };
            xmlHttp.send(data);    }
    回复楼上,我发送的是异步请求。
      

  9.   

    异步操作没问题,应该与session无关。
    this.xmlhttp.onreadystatechange = function(){Ajax.handleStateChange(objxml)};
    Ajax.handleStateChange = function (objxmlhttp) 
      {
         var xmlhttpstatus = "";
         if(objxmlhttp.readyState == 1)
          {
             xmlhttpstatus = "连接服务器";       
          }
         else if(objxmlhttp.readyState == 2)
         {
            xmlhttpstatus = "开始加载数据";       
         }
          else if(objxmlhttp.readyState == 3)
          {
              xmlhttpstatus = "正在加载数据";       
          }
         else if(objxmlhttp.readyState == 4)
         {
           if(objxmlhttp.status == 200)
            {
               xmlhttpstatus = "加载完成";       
             }    
         }
        else
        {
            xmlhttpstatus = "错误"+objxmlhttp.statusText;
        }
     }看看状态
      

  10.   

    回复楼上。
    在使用session后,ajax1未处理完前,也就是说ajax1状态为1时,ajax2请求的状态一直为1.
    当ajax1为2时,ajax2状态才开始2-3-4顺序变化,ajax2状态为4时,ajax1开始3-4。
    未使用session时,ajax1是否处理完,对ajax2没有影响。
      

  11.   

    服务器处理两个请求的代码,使用session的代码,跳转的代码,ajax的部分代码,我已经发上去了。
    就剩这个没法了。
            function ajax1()
            {
                var xmlHttp = new myXmlHttp();
                var doJS = function (jsString)
                {
                    eval(jsString);
                    initConnection();
                }
                xmlHttp.sendXmlHttp('Default.aspx?action=ajax1','',doJS);
            }
            function ajax2()
            {
                var xmlHttp = new myXmlHttp();
                var doJs = function(jsString){
                    eval(jsString);
                }
                xmlHttp.sendXmlHttp('Default.aspx?action=ajax2','',doJs);
            }
    <body onload="ajax1()">
    <input value="ajax2" type="button" onclick="ajax2();" />
      

  12.   

    上面有一点点代码发错了。服务器处理两个请求的代码,使用session的代码,跳转的代码,ajax的部分代码,我已经发上去了。 
    就剩这个没发了。         function ajax1()
            {
                var xmlHttp = new myXmlHttp();
                var doJS = function (jsString)
                {
                    eval(jsString);
                    ajax1();
                }
                xmlHttp.sendXmlHttp('Default.aspx?action=ajax1','',doJS);
            }
            function ajax2()
            {
                var xmlHttp = new myXmlHttp();
                var doJs = function(jsString){
                    eval(jsString);
                }
                xmlHttp.sendXmlHttp('Default.aspx?action=ajax2','',doJs);
            }<body onload="ajax1()">
    <input value="ajax2" type="button" onclick="ajax2();" />
      

  13.   

       xmlHttp.open("POST", url, true);        xmlHttp.onreadystatechange = function() {
                if (xmlHttp.readyState == 4) {
                    if (xmlHttp.status == 200) {
                        if (xmlHttp.responsetext != "") {
                            if(fun !=""&&fun !=undefined)
                            {
                                fun(xmlHttp.responsetext);
                            }
                        }
                    }
                }
            };
            xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            xmlHttp.send(data);先把位置改成这样在doJS  这个函数中,把返回值alert 一下然后运行 看看效果
      

  14.   

    要实现什么目的?
    XMLHttpRequest请求对象的状态
    还是根据Session["user"]的值来判断XMLHttpRequest请求的响应?
      

  15.   


    你没有看明白我的意思吧,我想我已经描述的比较清楚了。
    Session["user"]的值,跟任何东西没有直接关系。
    只是在使用Session后,ajax并发异步请求效果不一样。我要实现的是:
    求教牛人,如何在使用了session后,当ajax1未处理完成时,依然可以处理ajax2的请求?
      

  16.   

    刚才试了一下,这个问题和Session 没关系 是因为 你使用了 Thread.Sleep(8000);你让线程休眠了8秒钟,在这其间 对于 页面的访问都是堵塞的如果访问 需要使用多线程
      

  17.   

    请问,ajax异步请求,在服务器处理时不是多线程?
    还有,不使用session的时候,是不会堵塞的。这个你有试过么?
      

  18.   

    ajax异步请求, 指的是 不用等待请求的回应 可以继续操作,就是异步的发送请求。而响应则是服务器端的事, 如果一个请求将主线程 休眠,那其他请求 在此期间 是无法获得响应的我不知道你是怎么得出使用Session 会阻塞的结论。
      

  19.   

    我们暂时不讨论线程的问题了。你可以按照我的代码试试。
    Response.Write("alert('ajax1');");
    Response.Write("alert('ajax2');");
    ajax1和ajax2的请求得到处理后,都会返回aler的js代码提示。当不使用session时,点击Button触发ajax2,会立即alert("ajax2")
    而,当使用session时,点击Button触发ajax2,不会立即alert("ajax2")。只有等到延迟结束先alert("ajax1")后,才会alert("ajax2")。
      

  20.   

    还有,
    ajax异步请求, 指的是 不用等待请求的回应 可以继续操作,就是异步的发送请求。 
    这话是对的。
    是我刚才:"ajax异步请求,在服务器处理时不是多线程? "这话说的不准确。
    其实,我想说的是,无论同步还是异步请求,服务器每处理一个请求,都会分配一个线程。
    ajax1和ajax2是两个请求,也就是两条不同的线程。
      

  21.   

    你为什么就认为是 Session 导致 阻塞呢?你把Session 注释 自己试试
      

  22.   

    注释我试过很多次了。
    就是不使用session时啊,会立刻返回alert("ajax2");
    说明,注释掉session,就不会导致阻塞。
    你没有试吗?
      

  23.   

    我试过很多次,所以,我得到session阻塞的结论。这个只是个实验,这个问题是我在做即时通信时,遇到的问题,在即时通信中要在一定情况下,保持连接暂时不返回,就跟Thread.sleep类似。
    所以,意义肯定是有的。
      

  24.   

    我的意思是 如果我没试过的话 和你说是没有意义的。不是说 这个问题没意义。但这个问题的意义 也不在Session  ,因为原因不在它
      

  25.   

    这个问题确实是“session阻塞”,主要是每次请求他都必须等到session处理完才能处理下一个请求
    要不是那样的话,网站就全部乱套了,其实就是程序加锁了,必须把锁释放才能进行下一步操作,我建议楼主用其它技术来代替session,比如cache,application,Cookies等
      

  26.   

    这位,跟我的想法是一致的。
    但是,有个问题。
    我这里,就是登陆时,使用了session,ajax1和ajax2两个请求,都没有使用session,按道理,这两个请求不涉及session才对呀。
      

  27.   


    能否贴出你的ajax,以及后台代码?
      

  28.   

    其实,我觉得,代码加好锁,使用session也不会乱。
    不然,application不早乱了。所以,我继续等待解决方案。
    不用session会很痛苦的。
      

  29.   


            protected void Page_Load(object sender, EventArgs e)
            {
                //使用session的代码
                Session.Add("user", "aaa");
                switch (Request.QueryString["action"])
                {
                    case "ajax1":
                        Thread.Sleep(8000);
                        Response.Clear();
                        Response.Write("alert('ajax1');");
                        Response.End();
                        break;
                    case "ajax2":
                        Response.Clear();
                        Response.Write("alert('ajax2');");
                        Response.End();
                        break;
                }
            }
    就用你的代码就可以
    你把分别把线程和session注释,调试 看看是怎么回事
      

  30.   

    回复Sandy945,注释session我这边还是跟以往一样,不再阻塞。
    另外,我不明白,注释Thread.sleep干嘛?其他看到的朋友,帮我也测试一下。到底是我测试出错,还是Sandy945的?
      

  31.   

    Session实现了Reader/Writer的锁机制:  当页面对Session具有可写功能(即页面有<%@ Page EnableSessionState="True" %>标记),此时直到请求完成该页面的Session持有一个写锁定。  当页面对Session具有只读功能(即页面有<%@ Page EnableSessionState="ReadOnly" %>标记),此时知道请求完成该页面的Session持有一个读锁定。  读锁定将阻塞一个写锁定;读锁定不会阻塞读锁定;写锁定将阻塞所有的读写锁定。这就是为什么ajax1,ajax2都去写同一个Session时,ajax2要等待ajax1完成后,才开始写。
      

  32.   

    这个问题,看不出是不是session引起的.
    你现在的处理是同severlet的处理.thread的sleep有可能睡死了serverlet.导致serverlet不能异步.
    尝试放在不同的serverlet处理看看.
      

  33.   

    这个问题从昨天晚上开始睡觉困扰到我今天晚上不想睡觉.....
    终于按53楼,加一个EnableSessionState="ReadOnly" 搞定。顶!