Jeśli okaże się to przydatne dla każdego, z chęcią przełożę go na wspólnotową wiki.Więcej "ziarnistość" z Mini profilera MVC
Mam kilka wolnych stron w aplikacji MVC3, a ponieważ wydaje mi się, że w moim kodzie niewiele czasu wykonania wydarzyło się, chciałem sprawdzić, czy mogę dowiedzieć się więcej o tym, co trwało tak długo. Nie, że mi się udało, ale po drodze zyskałem trochę więcej mądrości.
Nie ma tu niczego, co nie byłoby oczywiste dla nikogo z doświadczeniem MVC. Zasadniczo, tworzę własne ActionFilterAttribute, który wygląda tak:
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"]);
}
To wydaje się działać dobrze, w moim przypadku nie dowiedział się, że przez większość czasu jest rzeczywiście spędził w części ResultExecuting życia, nie w moim działania.
Mam jednak kilka pytań na temat tego podejścia.
1) Czy jest to bezpieczny sposób robienia rzeczy? Zgaduję, nie, ponieważ filtr działania jest tworzony tylko raz, w metodzie RegisterGlobalFilters() w Global.asax.cs. Jeśli dwa żądania pojawią się jednocześnie, actionStep i resultStep będą bezwartościowe. Czy to prawda? Jeśli tak, czy ktoś, kto wie więcej niż ja, może w sprytny sposób poradzić sobie z tym? Działa dla mnie podczas lokalnego profilowania maszyn, ale prawdopodobnie nie jest tak dużo wdrożone na serwerze z wieloma osobami wysyłającymi żądania w tym samym czasie.
2) Czy istnieje sposób na uzyskanie lepszego wglądu w proces wykonywania wyników? A może powinienem zaakceptować, że renderowanie widoku itp. Zabiera czas? W mojej własnej aplikacji upewniam się, że cały dostęp do bazy danych został zakończony, zanim moja metoda działania zostanie zakończona (przy użyciu NHibernate Profiler w moim przypadku), a ja lubię utrzymywać moje widoki wąskie i proste; Każdy rodzaj wglądu w to, co spowalnia renderowanie może być jednak użyteczny. Myślę, że używając Mini Profiler w moich obiektach modelu pojawiłby się tutaj, gdyby został tutaj wykonany wolny kod z mojej strony.
3) Metody ResultDescriptor są prawdopodobnie złe i trujące. Pracowali dla mnie w moich testach, ale prawdopodobnie musieliby zostać zastąpieni przez coś solidniejszego. Po prostu poszedłem z pierwszymi wersjami, które dały mi coś w połowie użytecznego.
Wszelkie inne uwagi na ten temat również byłyby bardzo mile widziane, nawet jeśli brzmią "To zły pomysł, idźcie sami w spokoju".
Jeśli chcesz, aby żądania były bezpieczne, dlaczego nie używasz zdarzeń aplikacji związanych z cyklem życia żądania? http://stackoverflow.com/a/24197984/3481183 – Believe2014