【问题标题】:Dissabling Session in MVC3 to allow multiple AJAX calls在 MVC 3 中禁用 Session 以允许多个 AJAX 调用
【发布时间】:2012-03-03 17:04:53
【问题描述】:

同时执行多个 Ajax 调用会导致我的 MVC Web 应用程序阻塞。我一直在阅读,发现两个主题有相同的问题

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 禁用会话。我已尝试使用该属性,但我的代码仍处于阻塞状态。您可以使用以下代码重现创建新 MVC3 Web 应用程序的问题

@{
    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>

这是 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" } );
            }
        }
    }
}

非常感谢您。

【问题讨论】:

    标签: ajax asp.net-mvc-3


    【解决方案1】:

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

    我认为问题是由于如果您启动多个“SetACallWaiting”请求,您会遇到浏览器甚至不会将请求发送到服务器的情况,直到之前的请求没有得到答复 - 所以请求到“ReleaseEveryone”不是由浏览器发送的。因此,您将获得锁定行为。

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

    要测试这种行为,请查看浏览器发送的请求并在控制器的操作中设置断点,并查看它对于不同数量的请求的行为方式。

    【讨论】:

      猜你喜欢
      • 2012-05-22
      • 1970-01-01
      • 2019-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-28
      • 2012-01-16
      • 2012-12-07
      相关资源
      最近更新 更多