0

When doing multiple simultaneous Ajax calls cause my MVC web application to block. I have been reading and I found two topics with the same problem

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

The solution for them is disabling the session using ControllerSessionStateAttribute .I have try using the attribute but my code is still blocking. You can reproduce the problem creating a new MVC3 web application with the following code

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

and this is the 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" } );
            }
        }
    }
}

Thank you very much in advance.

Community
  • 1
  • 1
Azran
  • 263
  • 1
  • 3
  • 14

1 Answers1

0

I don't think this issue is actually related to the SessionState at all. Every browser makes only a limited number of concurrent requests to a domain - see this article for details.

I think the issue is caused by the fact that if you start multiple "SetACallWaiting" requests, you run into the situation where the browser won't even send the request to the server until the previous requests are unanswered - so the request to "ReleaseEveryone" is not sent by the browser. Therefore, you get the locking behaviour.

Also there may be an issue with the code sample you posted - the "SetCallWaiting(1000);" line in the function ShowResult. With this call, you won't actually reduce the number of waiting requests, as each time a request is released, it will be recreated again (I'm not sure if this is what you wanted or not).

To test this behaviour, look at the requests being sent by the browser and set breakpoints in the controller's actions, and see how it behaves for various umber of requests.

Community
  • 1
  • 1
Bogdan Banut
  • 101
  • 1
  • 6