您可能会看到的通常称为 .NET 中的线程敏捷性。
您可能会看到主题标签下的结果(即应用程序代码System.Web.HttpApplication.BeginRequest()
) 是线程敏捷性问题;在大多数情况下,您在这里看到的时间不一定是正在执行的代码,而是 Web 上下文正在等待线程从读写锁释放回它。
The Application_BeginRequest()
“暂停”在 ASP.NET Web 堆栈中非常普遍。一般来说,当您在 BeginRequest 中看到较长的加载时间时,您正在处理 ASP.NET 线程敏捷性和/或线程锁 - 特别是在处理 IO 和基于会话的操作时。这并不是一件坏事,这正是 .net 确保线程保持并发的方式。
时间间隔通常出现在 BeginRequest 和 PreRequestHandlerExecute 之间。如果应用程序正在向会话写入多个内容,则 ASP.NET 将发出读写锁HttpContext.Current.Session
.
查看这是否是您可能面临的问题的一个好方法是检查线程 ID,看看敏捷性是否是一个问题 - 对于给定的请求,ID 会有所不同。
例如。在调试时,也许您可以将以下内容添加到您的Global.asax.cs
:
protected void Application_BeginRequest(Object sender, EventArgs e) {
Debug.WriteLine("BeginRequest_" + Thread.CurrentThread.ManagedThreadId.ToString());
}
打开调试输出窗口(从 Visual Studio:查看>>输出,然后从“显示输出”下拉列表中选择“调试”)。
调试时,点击一个您已经看到很长时间的页面。然后查看输出日志 - 如果您看到多个 id,那么您可能会遇到这种情况。
这就是为什么您有时可能会看到延迟,但有时却看不到延迟,应用程序代码使用会话的方式可能略有不同,或者会话或 IO 操作可能会因页面而异。
如果是这种情况,您可以采取一些措施来帮助加快速度,具体取决于站点或每个给定页面上会话的使用方式。
对于不修改会话的页面:
<% @Page EnableSessionState="ReadOnly" %>
对于不使用会话状态的页面:
<% @Page EnableSessionState="False" %>
如果应用程序不使用会话(web.config):
<configuration>
<system.web>
<sessionState mode="Off" />
</system.web>
</configuration>
让我们看下面的例子:
用户加载一个页面,然后决定在第一个请求完成之前转到另一个页面,加载 ASP.NET 将强制会话锁定,导致新页面请求加载等待第一个页面请求完成。使用 ASP.NET MVC,每个操作都会锁定用户会话以进行同步;导致同样的问题。
释放锁所花费的所有时间都将通过 new relic 报告,更不用说用户放弃会话并且返回的线程正在寻找不再存在的用户的时间。
顺便说一句,UpdatePanel 控件会导致相同的行为 -
http://msdn.microsoft.com/en-us/magazine/cc163413.aspx http://msdn.microsoft.com/en-us/magazine/cc163413.aspx
可以做什么:
这个锁定问题是 Microsoft 拥有 SessionStateUtility 类的原因之一 -
http://msdn.microsoft.com/en-us/library/system.web.sessionstate.sessionstateutility.aspx http://msdn.microsoft.com/en-us/library/system.web.sessionstate.sessionstateutility.aspx
这样,如果您遇到此问题,您可以覆盖默认行为,如下所示
Redis实现:https://github.com/angieslist/AL-Redis https://github.com/angieslist/AL-Redis
基于 .net 的网站使用的默认状态提供程序有很多选项。但通常知道此事务时间表示线程正在被锁定并等待服务器的请求完成。