MVC 4 应用程序的一些用户正在经历零星的缓慢。大概不是每个用户每次遇到这个问题时都会报告这个问题。
我的想法是测量每个控制器操作所花费的时间,并记录超过规定时间的操作调用的详细信息,以便于进一步分析(以排除或排除服务器/代码问题)。
有没有一种方便的方法来执行此类测量,这样我就可以避免向每个操作添加检测代码?我目前没有在这个项目中使用 IOC,并且会犹豫引入它只是为了解决这个问题。
有没有更好的方法来解决这类问题?
MVC 4 应用程序的一些用户正在经历零星的缓慢。大概不是每个用户每次遇到这个问题时都会报告这个问题。
我的想法是测量每个控制器操作所花费的时间,并记录超过规定时间的操作调用的详细信息,以便于进一步分析(以排除或排除服务器/代码问题)。
有没有一种方便的方法来执行此类测量,这样我就可以避免向每个操作添加检测代码?我目前没有在这个项目中使用 IOC,并且会犹豫引入它只是为了解决这个问题。
有没有更好的方法来解决这类问题?
你能创建一个全局动作过滤器吗?像这样的东西:
public class PerformanceTestFilter : IActionFilter
{
private Stopwatch stopWatch = new Stopwatch();
public void OnActionExecuting(ActionExecutingContext filterContext)
{
stopWatch.Reset();
stopWatch.Start();
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
stopWatch.Stop();
var executionTime = stopWatch.ElapsedMilliseconds;
// Do something with the executionTime
}
}
然后GlobalFilters
在 `Application_Start()' 中将其添加到您的集合中
GlobalFilters.Filters.Add(new PerformanceTestFilter());
您可以从参数中获取有关正在测试的控制器的详细信息filterContext
。
更新
将过滤器GlobalFilters
直接添加到集合中将为所有操作创建一个过滤器实例。当然,这不适用于定时并发请求。要为每个操作创建一个新实例,请创建一个过滤器提供程序:
public class PerformanceTestFilterProvider : IFilterProvider
{
public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
return new[] {new Filter(new PerformanceTestFilter(), FilterScope.Global, 0)};
}
}
然后不是直接添加过滤器,而是在以下位置添加过滤器提供程序Application_Start()
:
FilterProviders.Providers.Add(new PerformanceTestFilterProvider());
我通常将这个简单的代码添加到布局视图的底部:
<!-- Page generated in @((DateTime.UtcNow - HttpContext.Current.Timestamp.ToUniversalTime()).TotalSeconds.ToString("F4")) s -->
输出类似:
<!-- Page generated in 0.4399 s -->
这开始测量HttpContext
创建的时间(根据文档),并在写入输出之前停止,因此它应该非常准确。
它可能不适用于所有用例(如果您想测量子操作,或忽略 MVC 操作之外的时间等),但它很容易粘贴到视图中。
对于更高级的诊断,我曾经使用Glimpse。
它检测页面渲染:您的应用程序的时间可能花费在控制器中,但有很多时间花费在视图渲染中。特别是如果你有很多部分和 html 助手。
更新 - 使用 Install-Package StopWatch 安装我的 Stopwatch NuGet 包,请参阅Profile and Time your ASP.NET MVC app all way to Azure
请参阅我的教程在 ASP.NET MVC 4 中使用异步方法, 它有一个全局操作过滤器计时器。您可以使用 ELMAH 来记录数据。我的示例 我的示例http://msdn.microsoft.com/en-us/library/gg416513(v=vs.98)也具有相同的定时过滤器并且更简单,但它是 Razor 之前的版本。
查找秒表属性以启用计时。
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
filters.Add(new UseStopwatchAttribute());
}
}