如果这对任何人都有用,我将很乐意将其转变为社区Wiki。
我在MVC3应用程序中有一些缓慢的页面,由于似乎很少执行时间发生在我的代码中,所以我想看看是否可以找到有关花费这么长时间的更多信息。并不是我成功了,但是在此过程中我获得了更多的智慧。
对于那些具有MVC经验的人来说,这里没有什么不是显而易见的。基本上,我创建了自己的ActionFilterAttribute,如下所示:
public class ProfilerAttribute : ActionFilterAttribute
{
IDisposable actionStep = null;
IDisposable resultStep = null;
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
actionStep = MiniProfiler.Current.Step("OnActionExecuting " + ResultDescriptor(filterContext));
base.OnActionExecuting(filterContext);
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (actionStep != null)
{
actionStep.Dispose();
actionStep = null;
}
base.OnActionExecuted(filterContext);
}
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
resultStep = MiniProfiler.Current.Step("OnResultExecuting " + ResultDescriptor(filterContext));
base.OnResultExecuting(filterContext);
}
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
if (resultStep != null)
{
resultStep.Dispose();
resultStep = null;
}
base.OnResultExecuted(filterContext);
}
private string ResultDescriptor(ActionExecutingContext filterContext)
{
return filterContext.ActionDescriptor.ControllerDescriptor.ControllerName + "." + filterContext.ActionDescriptor.ActionName;
}
private string ResultDescriptor(ResultExecutingContext filterContext)
{
var values = filterContext.RouteData.Values;
return String.Format("{0}.{1}", values["controller"], values["action"]);
}
这似乎运作良好,就我而言,我已经了解到,大部分时间实际上都花在了人生的ResultExecuting部分中,而不是花在我的行动中。
但是,我对此方法有一些疑问。
1)这是一种请求安全的处理方式吗?我猜不是,因为仅在Global.asax.cs的RegisterGlobalFilters()方法中创建了一个 Action 过滤器。如果同时出现两个请求,则actionStep和resultStep将一文不值。这是真的?如果是这样,那么一个比我了解更多的人可以为解决这个问题提供一个聪明的方法吗?在本地计算机性能分析期间对我有用,但可能部署在服务器上的人数很少,多个人同时发出请求。
2)有什么方法可以使您对结果执行过程有更多的了解?还是我应该接受渲染 View 等需要花费时间的问题?在我自己的应用程序中,我确保在我的操作方法结束之前(在我的情况下使用NHibernate Profiler),所有数据库访问都已完成,并且我希望保持 View 的简洁明了。但是,任何有关使渲染速度变慢的见解仍然有用。我想如果在这里执行任何慢速代码,在我的模型对象中使用Mini Profiler就会显示在这里。
3)ResultDescriptor方法可能是有害的。他们在我的测试中为我工作,但可能需要用更坚固的东西代替。我刚开始使用的第一个版本给了我一些有用的东西。
任何其他对此的评论也将受到欢迎,即使它们是“这是一个坏主意,请独自一人死去”。
最佳答案
这看起来很不错。我认为这不是要求安全的处理方式。
您可以像这样将其链接到HttpContext.Items
HttpContext.Items.Add("actionstep", actionStep);
HttpContext.Items.Add("resultstep", resultStep);
然后以类似的方式检索它
actionStep = HttpContext.Items["actionstep"];
resultStep = HttpContext.Items["resultstep"];
显然,您需要自己检查是否有null等。
每个用户/请求的
HttpContext
不同。关于
HttpContext.Current.Session.SessionID
要记住的一件事,我有时会忘记它是当前HTTP请求的SessionId(即,每次您按F5或发出新请求时,它都会更改)。要记住的另一件重要的事情是,尽管在任何时候,所有HttpContext.Current.Session.SessionID
值都必须是唯一的(即,每个用户或请求一个),它们可以被重用,因此不要将它们视为仅使用的GUID。每个一次。关于asp.net-mvc - 从MVC Mini Profiler获取更多 "granularity",我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6450847/