【发布时间】:2011-06-23 07:42:19
【问题描述】:
如果这对任何人都有用,我很乐意将它变成社区 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) 这是一种请求安全的做事方式吗?我猜不是,因为 actionfilter 只在 Global.asax.cs 的 RegisterGlobalFilters() 方法中创建一次。如果同时出现两个请求,actionStep 和 resultStep 将一文不值。这是真的?如果是这样,比我了解更多的人可以提供一个聪明的方法来处理这个问题吗?在本地机器分析期间为我工作,但可能没有那么多部署在多人同时发出请求的服务器上。
2) 有什么方法可以更深入地了解结果执行过程?还是我应该接受渲染视图等需要花费时间?在我自己的应用程序中,我确保在我的操作方法结束之前完成所有数据库访问(在我的情况下使用 NHibernate Profiler),并且我喜欢保持我的视图简洁明了;不过,任何关于减慢渲染速度的见解仍然是有用的。我猜在我的模型对象中使用 Mini Profiler 会显示在这里,如果我在这里执行了任何慢代码。
3) ResultDescriptor 方法可能是邪恶的和有毒的。它们在我的测试中为我工作,但可能需要用更强大的东西代替。我只是选择了第一个版本,它给了我一些有用的东西。
对此的任何其他 cmets 也将受到欢迎,即使他们是“这是个坏主意,独自去死”。
【问题讨论】:
-
如果你想要请求安全,为什么不使用与请求生命周期相关的应用程序事件呢? stackoverflow.com/a/24197984/3481183
标签: asp.net-mvc mvc-mini-profiler