为什么Global.asax.cs中的Session_Start会导致性能问题?
当我在 Global.asax.cs 中创建一个空的 Session_Start 处理程序时,在将页面渲染到浏览器时会导致严重的影响。
如何重现:
创建一个空的 ASP.NET MVC 3 Web 应用程序(我使用的是 MVC 3 RC2)。 然后使用以下代码添加一个 Home 控制器:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Number(int id)
{
return Content(id.ToString());
}
}
接下来创建一个视图 Home/Index.cshtml 并将以下内容放入 BODY 部分:
@for (int n = 0; n < 20; n++)
{
<iframe src="@Url.Content("~/Home/Number/" + n)" width=100 height=100 />
}
当您运行此页面时,您将看到页面上出现 20 个 IFRAME,每个 IFRAME 中都有一个数字。我在这里所做的只是创建一个页面,在幕后加载另外 20 个页面。在继续之前,请记下这 20 个页面的加载速度(刷新页面几次以重复加载)。
接下来转到 Global.asax.cs 并添加此方法(是的,方法主体为空):
protected void Session_Start()
{
}
现在再次运行该页面。这次您会注意到 20 个 IFRAME 的加载速度要慢得多,一个接一个的间隔大约为 1 秒。这很奇怪,因为我们实际上并没有在 Session_Start 中执行任何操作...它只是一个空方法。但这似乎足以导致所有后续页面的速度变慢。
有谁知道为什么会发生这种情况,更好的是有人有修复/解决方法吗?
更新
我发现这种行为仅在附加调试器(使用 F5 运行)时发生。如果您在没有附加调试器(Ctrl-F5)的情况下运行它,那么它似乎没问题。所以,也许这不是一个严重的问题,但仍然很奇怪。
When I create an empty Session_Start handler in Global.asax.cs it causes a significant hit when rendering pages to the browser.
How to reproduce:
Create an empty ASP.NET MVC 3 web application (I am using MVC 3 RC2).
Then add a Home controller with this code:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Number(int id)
{
return Content(id.ToString());
}
}
Next create a view Home/Index.cshtml and place the following in the BODY section:
@for (int n = 0; n < 20; n++)
{
<iframe src="@Url.Content("~/Home/Number/" + n)" width=100 height=100 />
}
When you run this page, you'll see 20 IFRAMEs appear on the page, each with a number inside it. All I'm doing here is creating a page that loads 20 more pages behind the scenes. Before continuing, take note of how quickly those 20 pages load (refresh the page a few times to repeat the loads).
Next go to your Global.asax.cs and add this method (yes, the method body is empty):
protected void Session_Start()
{
}
Now run the page again. This time you'll notice that the 20 IFRAMEs load much slower, one after the other about 1 second apart. This is strange because we're not actually doing anything in Session_Start ... it's just an empty method. But this seems to be enough to cause the slowdown in all subsequent pages.
Does anybody know why this is happening, and better yet does anybody have a fix/workaround?
Update
I've discovered that this behavior only occurs when the debugger is attached (running with F5). If you run it without the debugger attached (Ctrl-F5) then it seems to be ok. So, maybe it's not a significant problem but it's still strange.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
tl;dr:如果您在使用 Webforms 时遇到此问题,并且不需要对该特定页面中的会话状态进行写访问,请将
EnableSessionState="ReadOnly"
添加到您的@Page
指令有帮助。显然,仅
Session_Start
的存在就迫使 ASP.NET 按顺序执行源自同一会话的所有请求。但是,如果您不需要会话的写访问权限,则可以逐页修复此问题(见下文)。我已经使用 Webforms 创建了自己的测试设置,它使用 aspx 页面来传递图像。1
这是测试页面(纯 HTML,项目的起始页):
这是 aspx 页面 (GetImage.txt)。 aspx):
以及代码隐藏的相关部分 (GetImage.aspx.cs,
using
和namespace
已跳过):测试运行
< strong>Run 1,未修改:页面加载速度快,输出窗口显示
Start
和End
的随机组合,这意味着请求已得到处理并行。运行2,将空的
Session_Start
添加到global.asax
(需要在浏览器中按F5一次,不知道为什么这样is):Start
和End
交替出现,表明请求是按顺序处理的。多次刷新浏览器表明,即使未附加调试器,也会存在性能问题。运行 3,与运行 2 类似,但将
EnableSessionState="ReadOnly"
添加到GetImage.aspx 的
:调试输出在第一个@Page
指令中End
之前显示多个Start
。我们再次并行,并且性能良好。1 是的,我知道这应该使用 ashx 处理程序来完成。这只是一个例子。
tl;dr: If you face this problem with Webforms and don't require write access to session state in that particular page, adding
EnableSessionState="ReadOnly"
to your@Page
directive helps.Apparently, the existance of
Session_Start
alone forces ASP.NET to execute all requests originating from the same Session sequentially. This, however, can be fixed on a page-by-page basis if you don't need write access to the session (see below).I've created my own test setting with Webforms, which uses an aspx page to deliver images.1
Here's the test page (plain HTML, start page of the project):
Here's the aspx page (GetImage.aspx):
And the relevant parts of the codebehind (GetImage.aspx.cs,
using
andnamespace
skipped):Test runs
Run 1, unmodified: The page loads fast, the output window shows a random mix of
Start
andEnd
s, which means that the requests get processed in parallel.Run 2, add empty
Session_Start
toglobal.asax
(need to hit F5 once in the browser, don't know why this is):Start
andEnd
alternate, showing that the requests get processed sequentually. Refreshing the browser multiple times shows that this has performance issues even when the debugger is not attached.Run 3, like Run 2, but add
EnableSessionState="ReadOnly"
to the@Page
directive ofGetImage.aspx
: The debug output shows multipleStart
s before the firstEnd
. We are parallel again, and we have good performance.1 Yes, I know that this should be done with an ashx handler instead. It's just an example.
无法告诉您调试器正在做什么(intellitrace?详细日志记录?第一次机会异常?),但您仍然掌握会话处理并发请求的能力。
资料来源:ASP.NET 会话状态概述,我的重点
Can't tell you what your debugger is doing (intellitrace? detailed logging? first-chance exceptions?), but you're still in the hands of the sessions ability to handle concurrent requests.
Source: ASP.NET Session State Overview, my emphasis