Hedge - 这最终可能会成为一个“愚蠢的新手”问题,但如果不是,它可能会成为今天更有趣的帖子之一。
基本上,我发现仅仅将 Global.asax 组件添加到 Web 应用程序会导致运行时串行执行页面请求,而没有 Global.asax 的 Web 应用程序会按预期并行处理请求。如果您使用 Global.asax,影响将是可扩展性超出窗口 - 我怀疑实际情况是否如此,但目前我无法找到任何更好的解释。
场景如下:
- 创建一个新的空白网络应用程序。
添加一个需要 5 秒左右才能完成的页面。我使用了下面的方法,但延迟的确切方法似乎并不重要:
DateTime PageStartTime = DateTime.Now;
while (DateTime.Now < PageStartTime.AddMilliseconds(5000)) { System.Threading.Thread.Sleep(0);
添加另一个页面以用作重置应用程序域的实用程序。这并不是查看问题行为所必需的,但有助于重复测试:
HttpRuntime.UnloadAppDomain();
构建后,启动浏览器,其中一个选项卡(或窗口)用于应用域重置,3 个选项卡(或窗口)用于长时间运行的页面。
F5“重置”页面,稍等片刻,然后 F5 3 个“延迟页面”选项卡。您会看到(正如预期的那样)这 3 个页面几乎同时结束,即它们显然是并行运行的。运行所有你想要的 F5,它们仍然会按预期并行,大概直到奶牛回家。
返回项目,添加“全局应用程序类”(Gloabl.asax) 组件。无需添加任何代码 - 仅存在组件就是测试基础。
构建后,返回浏览器并快速 F5 4 个选项卡。同样,长时间运行的页面按预期并行运行,至少如果您相当快地点击 3 个选项卡。现在最重要的是 - 等待几秒钟直到全部完成,然后(不使用重置选项卡)再次 F5 3 个“延迟”页面 - 你会看到:
一个。所有 3 个运行的总时间约为 15 秒 - 比预期长 3 倍。这些页面似乎是按顺序处理的,即一个接一个地处理。
第二个和第三个选项卡的完成顺序是随机的,这表明 ASP 在第一个请求完成之前甚至没有决定哪个应该先运行。
如果您重置(卸载)应用程序域,您将有另一个机会让页面并行,但在它们完成第一个周期后,它们会立即返回串行执行。
回到项目,删除 Global.asax 组件,构建并重新测试 - 页面请求再次按预期进行长途并行。
很酷吧?
我尝试过的东西:
- 各种 .Net 版本 - 3.5 和 4,
- 各种网络服务器 - WebDev、UltiDev、IIS,
- 延迟页面的不同方式 - 实际工作,有和没有 yield 等,
- 浏览器使用情况 - 一个浏览器窗口有多个标签,与专用浏览器窗口相比,
- 代码放置 - 为延迟代码尝试了页面“加载”和“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/