2012-02-11 57 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函數中。通過這個調用,你實際上不會減少等待請求的數量,因爲每次請求被釋放時,它都會被重新創建(我不確定這是否是你想要的)。

要測試此行爲,請查看瀏覽器發送的請求並在控制器的操作中設置斷點,並查看其對於各種請求的行爲。