2012-02-11 58 views
0

在执行多个同时发生的Ajax调用时会导致我的MVC Web应用程序阻塞。我一直在读,我发现两个主题相同的问题在MVC3中禁用会话以允许多个AJAX调用

Why would multiple simultaneous AJAX calls to the same ASP.NET MVC action cause the browser to block?

Asynchronous Controller is blocking requests in ASP.NET MVC through jQuery

他们被禁止使用ControllerSessionStateAttribute。我有尝试使用该属性的会议,但我的代码是该解决方案仍然阻塞。您可以重现问题创建一个与下面的代码

@{ 
    ViewBag.Title = "Home Page"; 
} 

<h2>@ViewBag.Message</h2> 
<p> 
    Example of error when calling multiple AJAX, try click quickly on both buttons until the server get blocked. 
</p> 
<button onclick="cuelga++;SetCallWaiting(cuelga);">Set a call waiting in the server</button><button onclick="libera++;ReleaseEveryone(libera);">Release all calls in the server</button> 
<div id="text"></div> 
<script type="text/javascript"> 
    var cuelga = 0; 
    var libera =0; 

     function ReleaseEveryone(number) { 
      var url = "/Home/ReleaseEveryone/"; 
      $.post(url, { "id": number }, 
       ShowResult1, "json"); 

     }; 

     function SetCallWaiting(number) { 

      var url = "/Home/SetACallWaiting/"; 
      $.post(url, { "id": number }, 
       ShowResult, "json"); 
     }; 

     function ShowResult (data) { 
      $("#text").append(' [The call waiting number ' + data[0] + ' come back ] '); 
      /* When we come back we also add a new extra call waiting with number 1000 to make it diferent */ 
      SetCallWaiting(1000); 
     }; 
     function ShowResult1(data) { 
      $("#text").append(' [The release call number ' + data[0] + ' come back ] '); 
     }; 
</script> 

新MVC3 Web应用程序,这是HomeController的

using System; 
using System.Collections.Generic; 
using System.Web.Mvc; 
using System.Threading; 
using System.Web.SessionState; 

namespace ErrorExample.Controllers 
{ 
    [SessionState(SessionStateBehavior.Disabled)] 
    public class HomeController : Controller 
    { 
     private static List<EventWaitHandle> m_pool = new List<EventWaitHandle>(); 
     private static object myLock = new object(); 


     public ActionResult Index() 
     { 
      ViewBag.Message = "Welcome to ASP.NET MVC!"; 

      return View(); 
     } 

     public ActionResult About() 
     { 
      return View(); 
     } 

     [HttpPost] 
     public JsonResult SetACallWaiting() 
     { 
      EventWaitHandle myeve; 
      lock (myLock) 
      { 
       myeve = new EventWaitHandle(false, EventResetMode.ManualReset); 
       m_pool.Add(myeve); 
      } 
      myeve.WaitOne(); 

      var topic = HttpContext.Request.Form[0]; 
      return Json(new object[] { topic }); 
     } 

     [HttpPost] 
     public JsonResult ReleaseEveryone() 
     { 
      try 
      { 
       lock (myLock) 
       { 
        foreach (var eventWaitHandle in m_pool) 
        { 
         eventWaitHandle.Set(); 
        } 
        m_pool.Clear(); 
       } 
       var topic = HttpContext.Request.Form[0]; 
       return Json(new object[] { topic }); 
      } 
      catch (Exception) 
      { 
       return Json(new object[] { "Error" }); 
      } 
     } 
    } 
} 

非常感谢你提前。

回答

0

我不认为这个问题实际上与SessionState有关。 每个浏览器只向域发出有限数量的并发请求 - 有关详细信息,请参阅this article

我认为这个问题是由以下事实引起的,如果你启动多个“SetACallWaiting”请求,你会遇到浏览器甚至不会将请求发送到服务器直到前面的请求未被回答的情况 - 所以浏览器不发送“Release Allive”请求。因此,你会得到锁定行为。

此外,您发布的代码示例可能存在问题 - “SetCallWaiting(1000);”在ShowResult函数中。通过这个调用,你实际上不会减少等待请求的数量,因为每次请求被释放时,它都会被重新创建(我不确定这是否是你想要的)。

要测试此行为,请查看浏览器发送的请求并在控制器的操作中设置断点,并查看其对于各种请求的行为。