Если это окажется полезным для всех, я с удовольствием превращу это в вики-сообщество.
У меня есть несколько медленных страниц в приложении 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 создается только один раз, в методе RegisterGlobalFilters () в Global.asax.cs. Если два запроса появляются одновременно, actionStep и resultStep будут бесполезны. Это правда? Если так, может ли кто-нибудь, кто знает больше меня, предложить умный способ справиться с этим? У меня работает во время профилирования локальной машины, но, возможно, не так много развернуто на сервере, когда несколько человек делают запросы одновременно.
2) Есть ли способ получить более полное представление о процессе выполнения результата? Или я должен просто согласиться с тем, что рендеринг вида и т. Д. Требует времени? В моем собственном приложении я гарантирую, что весь доступ к базе данных будет завершен до того, как мой метод действия будет завершен (с использованием NHibernate Profiler в моем случае), и мне нравится сохранять свои взгляды тонкими и простыми; Любое понимание того, что замедляет рендеринг, может быть полезным. Я предполагаю, что использование Mini Profiler в моих модельных объектах появилось бы здесь, если бы здесь выполнялся медленный код с моей стороны.
3) Методы ResultDescriptor, вероятно, злые и ядовитые. Они работали на меня в моих тестах, но, вероятно, нужно было бы заменить что-то более надежное. Я просто пошел с первыми версиями, которые дали мне что-то наполовину полезное.
Любые другие комментарии к этому также будут приветствоваться, даже если они "Это плохая идея, иди умри в одиночестве".