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

标签 c# asp.net multithreading

Hedge - 这最终可能会成为一个“愚蠢的新手”问题,但如果不是,它可能会成为今天更有趣的帖子之一。

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

场景如下:

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

    DateTime PageStartTime = DateTime.Now;

    while (DateTime.Now < PageStartTime.AddMilliseconds(5000)) { System.Threading.Thread.Sleep(0);

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

    HttpRuntime.UnloadAppDomain();

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

  5. F5“重置”页面,稍等片刻,然后 F5 3 个“延迟页面”选项卡。您会看到(正如预期的那样)这 3 个页面几乎同时结束,即它们显然是并行运行的。运行所有你想要的 F5,它们仍然会按预期并行,大概直到奶牛回家。

  6. 返回项目,添加“全局应用程序类”(Gloabl.asax) 组件。无需添加任何代码 - 仅存在组件就是测试基础。

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

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

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

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

  8. 回到项目,删除 Global.asax 组件,构建并重新测试 - 页面请求再次按预期进行长途并行。

很酷吧?

我尝试过的东西:

  1. 各种 .Net 版本 - 3.5 和 4,
  2. 各种网络服务器 - WebDev、UltiDev、IIS,
  3. 延迟页面的不同方式 - 实际工作,有和没有 yield 等,
  4. 浏览器使用情况 - 一个浏览器窗口有多个标签,与专用浏览器窗口相比,
  5. 代码放置 - 为延迟代码尝试了页面“加载”和“PreRender”事件, ~。其他的东西现在从白发苍苍的内存中消失了……

显然以上不是一个有代表性或有用的项目,但我无意中发现了这个有意长时间运行的页面和对 Global.asax 的实际需求——主要用于全局静态变量。我想大多数“普通”Web 应用程序的运行速度都足够快,如果它们恢复为顺序请求执行,很少有人会注意到,但这种行为确实打破了我的想法 - 已经敲了三天,所以任何想法都非常感谢!

谢谢, 大卫

最佳答案

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

protected void Session_Start(object sender, EventArgs e)
{

}

此事件处理程序的存在导致 ASP.NET 创建实际 session 并将其与 session cookie 相关联,即使您从未在 session 状态中存储任何内容。一旦有实际 session ,requests are serialized .

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

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

关于c# - ASP.Net - Global.asax 的存在阻止并行请求执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19082583/

相关文章:

c# - 将 C# 属性应用于扩展方法以像操作过滤器一样管理扩展方法的执行

jquery - Rowcommand 没有为 gridview 中的 linkbutton 触发?

asp.net - WebApi 字符串操作中的 IModelBinder

Ruby 线程限制 - 也适用于任何语言

python - 线程之间的简单字节流是否需要 Python 队列?

java - 一个函数多次调用 : why ? 以及通过 C 线程使用不当?

c# - 代码合约警告

c# - 获取每秒滴答数并转换为字符串值?

c# - 将两条短裤放入字节数组

c# - ASP.NET MVC3 - "Object reference not set to an instance of an object"错误