您可能会看到在 .NET 中通常被称为线程敏捷性。
就主题标签下的结果(即 中的应用程序代码)而言,您可能看到的System.Web.HttpApplication.BeginRequest()
是线程敏捷性问题;在大多数情况下,您在这里看到的时间不一定是正在执行的代码,而是 Web 上下文等待线程从读写锁释放回给它。
“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
可以做什么:
这个锁定问题是微软拥有 SessionStateUtility 类的原因之一 -
http://msdn.microsoft.com/en-us/library/system.web.sessionstate.sessionstateutility.aspx
因此,如果您遇到此 Redis 实现中看到的问题,您可以覆盖默认行为:https ://github.com/angieslist/AL-Redis
基于 .net 的网站使用的默认状态提供程序有很多选项。但是通常知道这个事务时间表明线程被锁定并等待对服务器的请求完成。