ASP.Net - Global.asax 的存在会阻止并行请求执行

本文关键字:并行 请求 执行 存在 Net Global asax ASP | 更新日期: 2023-09-27 18:33:18

对冲 - 这最终可能是一个"愚蠢的新手"问题,但如果不是,它可能是今天更有趣的帖子之一。

基本上,我看到仅将 Global.asax 组件添加到 Web 应用程序会导致运行时串行执行页面请求,而没有 Global.asax 的 Web 应用程序按预期并行处理请求。 如果您使用 Global.asax,影响将是可扩展性消失了 - 我怀疑实际情况是否如此,但目前被阻止了任何更好的解释。

场景如下:

  1. 创建新的空白 Web 应用程序。
  2. 添加一个需要 5 秒左右才能完成的页面。 我使用了以下内容,但延迟的确切方法似乎并不重要:

    日期时间页面开始时间 = 日期时间.现在;

    while (DateTime.Now

  3. 添加另一个页面以用作实用程序以重置应用程序域。 这不是查看问题行为的严格必要条件,但有助于重复测试:

    HttpRuntime.UnloadAppDomain((;

  4. 构建后,启动一个浏览器,其中包含一个选项卡(或窗口(用于重置应用程序域,3 个选项卡(或窗口(用于长时间运行的页面。

  5. F5 "重置"页面
  6. ,等待一秒钟,然后 F5 3 个"延迟页面"选项卡。 你会看到(正如预期的那样(这 3 页大约在同一时间结束,即它们显然是并行运行的。 运行您想要的所有 F5,它们仍将按预期并行,大概直到奶牛回家。

  7. 返回到项目,添加一个"全局应用程序类"(Gloabl.asax(组件。 无需添加任何代码 - 仅组件的存在就是测试基础。

  8. 构建后,返回浏览器并快速 F5 4 个选项卡。 同样,长时间运行的页面按预期并行,至少如果您相当快地点击 3 个选项卡。 现在好的部分 - 等待一秒钟直到全部完成,然后(不使用重置选项卡(F5 再次 3 个"延迟"页面 - 您将看到:

    一个。所有 3 个运行的总时间约为 15 秒 - 比预期长 3 倍。 这些页面似乎是连续处理的,即一个接一个。

    二.第二个和第三个选项卡的完成顺序是随机的,这表明 ASP 甚至还没有决定哪个应该先运行,直到第一个请求完成之后。

    三.如果重置(卸载(应用程序域,您将有另一个机会使页面并行,但在它们完成第一个周期后,它们会立即返回到串行执行。

  9. 返回到项目,删除 Global.asax 组件,生成并重新测试 - 页面请求再次并行,按预期进行长期传输。

很酷吧?

我尝试过的东西:

  1. 各种 .Net 版本 - 3.5 和 4,
  2. 各种Web服务器 - WebDev,UltiDev,IIS,
  3. 延迟页面的不同方式 - 实际工作,有和没有产量等,
  4. 浏览器使用情况 - 一个具有多个选项卡的浏览器窗口,与专用浏览器窗口相比,
  5. 代码放置 - 尝试了延迟代码的页面"加载"和"预呈现"事件,~.其他东西现在从白发苍苍的记忆中滚落......

显然,以上不是一个具有代表性或有用的项目,但我偶然发现了这个做一些既有意长时间运行的页面又有对 Global.asax 的实际需求的事情——主要是全局静态变量。 我想大多数"正常"的 Web 应用程序都会运行得足够快,以至于很少有人会注意到它们是否恢复到顺序请求执行,但这种行为肯定会破坏我的 - 已经敲定了三天,所以任何想法都非常感谢!

谢谢大卫

ASP.Net - Global.asax 的存在会阻止并行请求执行

罪魁祸首是默认添加到 Global.asax 的Session_Start事件处理程序.cs:

protected void Session_Start(object sender, EventArgs e)
{
}

此事件处理程序的存在会导致 ASP.NET 创建实际会话并将其与会话 Cookie 关联,即使您从未在会话状态中存储任何内容也是如此。一旦有实际会话,请求就会被序列化。

在你的方案中,只需删除空的 Session_State 事件处理程序,请求将再次并行执行。

(Global.asax.cs 中还有一个空的 Session_End 事件处理程序,但它不会影响请求是否序列化。

我的猜测是,由于某种原因,您为请求分配了一个会话,并且不同的浏览器选项卡/窗口共享同一会话。如果是这样,运行时将按顺序执行请求。

ASP.net 会话请求排队

ASP.NET MVC 和 Ajax,并发请求?

如果使用 http 调试器嗅探流量,则可以轻松验证这一点。

ASP.NET 会话可能使您的请求处于挂起状态...

请尝试以下代码。页面中提供了更多信息

[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]
public class HomeController : Controller
{
}