【问题标题】:ASP.NET MVC + jQuery + IIS6: Multiple Ajax requestsASP.NET MVC + jQuery + IIS6:多个 Ajax 请求
【发布时间】:2009-05-13 21:17:22
【问题描述】:

我不确定问题出在哪里......

我有一个 ajax 请求,该请求在包含包裹列表的页面上检查包裹的跟踪信息:

$(".fedex_status").each(function () {
    var item = this;
    // some code to construct tracking_url

    $.ajax({
        type: "GET",
        url: tracking_url,
        async: true,
        cache: false,
        success: function (data) { $(item).html("(" + data + ")"); },
        error: function () { $(item).html("request failed..."); }
    });
});

因此,如果页面上有 10 个包(10 个带有“fedex_status”类的东西),则会创建 10 个请求。请求工作正常,但一次返回一个结果(以串行方式)。我在控制器操作中为请求的开始和停止添加了时间戳:

public ActionResult Fedex(string trackingNumber)
{
    DateTime requestStart = DateTime.Now;
    TrackingService tracking = new TrackingService();
    string status = tracking.FedexTrackingNumberStatus(trackingNumber);
    return Content(status + " - " + requestStart.ToString("hh:mm:ss.FFF") + " - " + DateTime.Now.ToString("hh:mm:ss.FFF"));
}

所有时间戳都不重叠。所以控制器一次处理一个请求。这看起来很糟糕。

现在,ajax 请求“应该”是并行的。它肯定会立即返回(它是异步的)。当我查看 IIS 日志时,请求的时间戳与控制器操作返回的时间戳相同。

所以我的问题是:jquery 是不是并行发送所有 ajax 请求,还是 IIS 或 ASP.NET 仅串行处理请求。我是 IIS 和 ASP.NET 技术细节的大菜鸟,所以它可能永远被错误配置,并且一次只响应一个请求(仅限内部使用,低流量)。也就是说,我也是 jquery 的白痴,不知道如何测试请求何时被实际触发(我所知道的是 $.ajax 调用立即返回)。

谢谢!

【问题讨论】:

    标签: asp.net jquery asp.net-mvc iis iis-6


    【解决方案1】:

    理论上,启用会话状态的 ASP.NET 会为每个用户请求锁定会话,从而串行处理它们。我不认为您可以轻松地为 MVC 项目禁用 Session,因为 TempData 例如默认使用会话。不过你可以试试。

    编辑:这是related question

    【讨论】:

    • 这很不幸。实际上,我在其他地方使用临时数据(给用户的消息,如“已创建货件!”之类的废话),所以我不能只是摆脱它。不过,这个特定的控制器永远不需要 TempData 或 Session。我想知道在控制器级别禁用 TempData 是否会有所帮助,或者在 web.config 中未禁用会话这一事实胜过控制器是否使用它。
    • 我认为这仅在部分情况下是正确的(我想到了 aspcompt=true)。我不认为 session 本身会导致所有请求都被序列化。
    • @Erv:我已经阅读了一些内容,因为这个答案是在标准 ASP.NET 中,您可以在每页的基础上指定会话所需的锁定类型。默认情况下,我认为它是一个作家锁,每页只允许 1 个请求。您可以将其更改为允许多个读取器的读取器锁,但会阻止写入器,并会阻止持有锁的写入器。我不知道如何将这些应用到 ASP.NET MVC。我只想说“在任何地方都使用读卡器锁”,因为我使用会话状态并没有什么特别的。
    • 我使用指令“EnableSessionState="False"”创建了一个 WebForm 页面,该指令执行与 ASP.NET MVC 操作相同的功能。我肯定会在 IE7 中一次收到 2 个并行请求(这是每个域的限制吗?)。我在 chrome 中尝试过,我认为它比 2 多一点,但很难准确地说出来。在我看来,它至少与会话相关。下一个问题是如何在 ASP.NET MVC 中解决这个问题。谢谢大家!
    【解决方案2】:

    您的代码在我的机器上按预期工作。我不得不在 Thread.Sleep 中插入任何人为延迟才能看到它的实际效果,因为纯粹的请求执行得如此之快,以至于看起来它们都立即完成了。

     System.Threading.Thread.Sleep(1000);
    
     return Content(String.Format("Thread #{0}, Started = {1:hh:mm:ss.FFF}, Completed = {2:hh:mm:ss.FFF}, Duration = {3:hh:mm:ss.FFF}, Result = {4}",
           System.Threading.Thread.CurrentThread.ManagedThreadId,
           requestStart,
           DateTime.Now,
           DateTime.Now.Subtract(requestStart),
           status));
    

    在我的机器上使用 Firefox 并连接到内置的 Visual Studio Web 服务器的快速测试表明,两个请求在客户端同时执行,并由服务器上的两个不同线程处理。

    据我所知,浏览器允许的并发请求数量有限。这是关于 SO 的另一篇文章,其中涵盖了每个流行浏览器的每个值:How many concurrent AJAX (XmlHttpRequest) requests are allowed in popular browsers?

    编辑:我重读了您的帖子,发现您提到了 IIS 6。我无权访问 IIS 6,但在 IIS 7 Web 服务器上以 5 秒人为超时(Thread.Sleep)运行它表明多个请求由不同的服务器线程同时处理。它们都不是在完全相同的时间开始的,所以服务器上可能会有一些排队,但是有 5 秒的延迟很容易看出在 Firefox 3.0 中我一次至少有 6 个并发请求。

    【讨论】:

    • 我将不得不再玩这个。我的 ASP.NET MVC 实现中的操作代码与 ASP.NET WebForms 代码相同(WebForms 解析查询字符串除外)。除此之外,唯一的区别是 WebForms 中禁用会话的变化。我很肯定,由于某种锁定,我从 WebForms 中获得了比 ASP.NET MVC 更好的性能。如果您从 ASP.NET MVC 中同时收到 2 个请求,那么我需要深入挖掘。谢谢!
    • 您是否有理由不希望使用所有跟踪号执行单个请求,然后解析返回的数据并更新 UI 而不是多次调用?
    • 一些,最值得注意的是这更容易。但是即使忽略这一点,如果我发送了一个带有跟踪号码数组的请求,我就必须在服务器级别连续执行它们,或者负责产生一堆线程或使我的服务异步。当我有一个 http 和一个 Web 服务器来为我做这一切时,为什么还要经历这些麻烦。在一般情况下(不用于跟踪信息)我想探索像 igoogle 小部件这样的东西,它们通过 ajax 完成所有加载。所以你有一个门户主页,然后是一堆 ajax 调用来加载页面。
    • @您的编辑:显然 6 个并发请求对我来说足够并行。只需一个请求,可能需要 5-10 秒。即使一次只有两个,这也是一个巨大的改进(它在 FF3 / Chrome 中冒烟)。我对现在通过 WebForms 的性能感到满意,但确实希望更进一步地了解 ASP.NET MVC 是否达到相同的水平。 IIS6 和 7 之间的区别很有趣。我在家里有 Vista,但在工作中只有 2k3 / XP。我想我可以在家里试一试。
    【解决方案3】:

    每次您找到具有 .fedex_status 类的元素时,您都会调用您的 ajax 请求。

    你的线路

    $(".fedex_status").each

    是说每次你找到一个 .fedex_status 类的元素时都这样做。

    【讨论】:

    • 是的,就是这样。因此,如果我有 10 个 fedex_status 匹配项,我想并行调用 10 个 ajax 请求并让每个请求异步返回。现在它们正在串行完成(虽然不是真正同步......请求立即返回,所以它是异步的,但请求是串行处理的)。我不知道是它的客户端还是服务器端使事情成为串行而不是并行。
    • 请求不会并行运行,因为您一个接一个地调用它们!我对 JSON 了解不多,但您可以在一个 ajax 请求中返回 JSON 格式的信息,然后循环遍历 json 并将数据插入 dom。不确定只是一个想法。
    • 所以一次只能有1个ajax请求?
    • async: true 标志,所以请求被并行发送,但在服务器端被串行处理。顺便说一句,我建议使用 Fiddler 之类的工具来调试您的 HTTP 会话。
    • @Rigobert 在这里搞错了。一次可以有多个 AJAX 请求! AJAX 对象中指定的回调在请求返回时被调用,因此 .Each() 函数在请求完成之前不会阻塞;它在请求被分派后立即继续,并且该请求在浏览器的后台线程上运行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多