これが誰かにとって役立つことが判明した場合、私は喜んでそれをコミュニティ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()メソッドで一度だけ作成されるので、私はノーと推測しています。2つのリクエストが同時に表示される場合、actionStepとresultStepは無意味になります。これは本当ですか?もしそうなら、私よりも知っている誰かがこれを処理するための賢い方法を提供できますか?ローカルマシンのプロファイリング中には機能しますが、複数の人が同時にリクエストを行うサーバーにはあまりデプロイされていない可能性があります。
2)結果実行プロセスについてより多くの洞察を得る方法はありますか?それとも、ビューのレンダリングなどに時間がかかることを受け入れる必要がありますか?私自身のアプリでは、アクションメソッドが終了する前にすべてのデータベースアクセスが終了することを確認し(私の場合はNHibernate Profilerを使用)、ビューをスリムでシンプルに保つのが好きです。ただし、レンダリングの速度を低下させる原因についてのあらゆる種類の洞察は、依然として役立つ可能性があります。私の側でスローコードがここで実行された場合、モデルオブジェクトでミニプロファイラーを使用するとここに表示されると思います。
3)ResultDescriptorメソッドは、おそらく邪悪で有毒です。彼らは私のテストで私のために働いたが、おそらくもっと頑丈なものに置き換える必要があるだろう。私はちょうど私に中途半端に役立つ何かを与えた最初のバージョンで行きました。
「これは悪い考えです、一人で死ぬ」であっても、これに対する他のコメントも大歓迎です。