【问题标题】:AJAX requests are not being handled completely asynchronously for long running requests对于长时间运行的请求,AJAX 请求没有被完全异步处理
【发布时间】:2014-12-04 19:12:26
【问题描述】:

我有一个页面,其中包含每 5 秒触发一次的 AJAX 轮询请求以及可能需要一分钟才能完成的其他 AJAX CRUD 操作。似乎正在发生的是轮询请求每 5 秒执行一次并完成一次,除非正在处理长时间运行的请求 - 在这些长时间运行的执行场景中,轮询请求的 beforeSend 事件将触发,但不会命中控制器,直到长时间运行的请求完成。轮询请求只是排队等待,直到长时间运行的请求完成,此时它将执行排队的轮询请求。

我使用测试方法和 30 秒的线程休眠在我现有的解决方案(结果如下)中重新创建了场景,以模拟长时间运行的数据库事务。您会注意到,当TestSlowMethod30Seconds() 开始时,TestRequest() 调用开始排队,只有在TestSlowMethod30Seconds() 完成后,TestRequest() 调用才完成。

如果我使用基本的 MVC VS 模板创建一个全新的解决方案并执行相同的操作,它会按预期工作并且长时间运行的请求不会影响其他请求 - 它们都是完全异步处理的。

我花了一整天的时间进行此测试,但我终其一生都无法弄清楚我现有解决方案的问题所在。

有人有什么想法吗?

var ajaxTest = namespace("test.ajaxTest");

ajaxTest.init = function () {
    window.setInterval(function () {
        ajaxTest.TestRequest();
    }, 5000);
};


ajaxTest.TestRequest = function () {
    $.ajax({
        type: "POST",
        url: "/Test/TestRequest",       
        beforeSend: function () {
            console.log("*** TestRequest() begin");
        },
        complete: function () {
            console.log("*** TestRequest() complete");
        }           
    });
};

// this method is called from a button click event
ajaxTest.TestSlowMethod30Seconds = function () {    
    $.ajax({
        type: "POST",
        url: "/Test/TestSlowMethod30Seconds",       
        beforeSend: function () {
            console.log("*** TestSlowMethod30Seconds() begin");
        },
        complete: function () {         
            console.log("*** TestSlowMethod30Seconds() complete");
        }           
    });
};

MVC 测试控制器

public ActionResult TestRequest()
{
    return Json("Success");
}

public ActionResult TestSlowMethod30Seconds()
{
    System.Threading.Thread.Sleep(30000);

    return Json("Success");
}

【问题讨论】:

    标签: c# ajax asp.net-mvc


    【解决方案1】:

    会话状态。如果您的请求使用会话状态,则请求将被序列化。如果您不希望它们被序列化,那么您的服务器端代码将需要在没有会话状态的情况下运行或标记为仅使用只读会话状态

    【讨论】:

    • 请求未使用会话状态。正如您在上面看到的,控制器方法非常简单。
    • 如果这是asp.net,我相信即使您没有在控制器中使用它,它们也会默认使用会话状态
    • 你在现场!通过用 [SessionState(SessionStateBehavior.ReadOnly)] 装饰控制器使其工作。我想知道为什么我的新 MVC 测试应用程序无需设置会话状态行为就可以工作,但是当我通过在控制器中向会话添加一些内容进行测试时会导致相同的行为
    【解决方案2】:

    您的浏览器可能已达到最大并行连接数限制:

    Max parallel http connections in a browser?

    您需要减少并发请求的数量 - 只保留一个长池请求或切换到其他技术,如 Web 套接字或服务器端事件。

    还有一个有用的库叫做signalr

    顺便说一句:尝试打开更多选项卡,您会发现更多滞后

    【讨论】:

    • 我不明白这是怎么回事。如果我将布局页面剥离到最简单的部分,那么它只是试图执行的两个测试请求。
    • 您的日志中的@MarkErasmus:您开始了 1 个长请求,然后是 6 个测试请求(一两个(我不确定)测试请求将等待长请求完成)。
    • @MarkErasmus 尝试打开超过 6 个长请求,您会注意到请求 (7,8) 将等待前一个完成
    • @MarkErasmus 还检查 Mikes 的答案并尝试使用 [SessionState(SessionStateBehavior.ReadOnly)] 来装饰您的控制器
    猜你喜欢
    • 1970-01-01
    • 2011-01-23
    • 1970-01-01
    • 2012-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-27
    • 1970-01-01
    相关资源
    最近更新 更多