使用MiniProfiler跟踪MVC + EF + Bootstrap 2 权限管理系统的性能消耗

安装MiniProfiler

MVC + EF + Bootstrap 2 权限管理系统入门级(附源码)文章中下载了它的源码,调试模式下打开一个页面都要再2.5秒以上,所以使用MiniProfiler、MiniProfiler.MVC4 、MiniProfiler.EF6组件进行了分析。

首先,依次序安装组件。然后,修改Global.aspx.cs 文件:

 protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles); //自定义View
ViewEngines.Engines.Clear();
ExtendedRazorViewEngine engine = new ExtendedRazorViewEngine();
engine.AddPartialViewLocationFormat("~/Areas/Common/Views/Shared/{0}.cshtml");
engine.AddPartialViewLocationFormat("~/Areas/Common/Views/Shared/{0}.vbhtml");
ViewEngines.Engines.Add(engine); //Model去除前后空格
ModelBinders.Binders.DefaultBinder = new TrimModelBinder(); //设置MEF依赖注入容器
MefConfig.RegisterMef(); //初始化EF6的性能监控
MiniProfilerEF6.Initialize(); //初始化DB
DatabaseInitializer.Initialize();
} protected void Application_BeginRequest()
{
StackExchange.Profiling.MiniProfiler.Start();
}
protected void Application_EndRequest()
{
StackExchange.Profiling.MiniProfiler.Stop();
}

MiniProfilerEF6.Initialize(); 一定要放在 DatabaseInitializer.Initialize(); 之前,否则会报如下错误:

An exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll but was not handled in user code. Additional information: The Entity Framework was already using a DbConfiguration instance before an attempt was made to add an 'Loaded' event handler. 'Loaded' event handlers can only be added as part of application start up before the Entity Framework is used."

运行站点有可能还会遇到这个错误:

An exception of type 'System.Data.SqlClient.SqlException' occurred in MiniProfiler.dll but was not handled in user code

Additional information: Invalid column name 'CreatedOn'.

解决方法是:

1.禁用这种类型的异常断点(不可取)

2.删除packages\MiniProfiler.3.2.0.157\lib\net40 下的MiniProfiler.PDB文件(我是这么做的)

3.禁用EF的数据库变化跟踪(未验证,应该管用)

Found an answer for my question. Thanks all for replies.

Database.SetInitializer<MyContext<Label>>(null);
This fixes the problem and disables DB changes tracking in EF.

运行站点打开登陆页

使用MiniProfiler跟踪MVC + EF + Bootstrap 2 权限管理系统的性能消耗

Sql占了47.7%,点开可以查看执行了哪些sql语句。

分析页面耗时

首先,调试模式下运行Debug和Release代码,耗时差不多都很长,截图如下:

使用MiniProfiler跟踪MVC + EF + Bootstrap 2 权限管理系统的性能消耗    使用MiniProfiler跟踪MVC + EF + Bootstrap 2 权限管理系统的性能消耗

使用MiniProfiler跟踪MVC + EF + Bootstrap 2 权限管理系统的性能消耗   使用MiniProfiler跟踪MVC + EF + Bootstrap 2 权限管理系统的性能消耗

然后,非调试模式(Ctrl+F5)运行,截图如下:

使用MiniProfiler跟踪MVC + EF + Bootstrap 2 权限管理系统的性能消耗使用MiniProfiler跟踪MVC + EF + Bootstrap 2 权限管理系统的性能消耗

非调试模式(Ctrl+F5)的效率还是挺不错的,没想到和调试模式(F5)差别会这么大。使用必应搜了一下找到一个帖子 :Visual C++: Difference between Start with/without debugging in Release mode

里面的解释是

The problem is that Windows drops in a special Debug Heap, if it detects that your program is running under a Debugger. This appears to happen at the OS level, and is independent of any Debug/Release mode settings for your compilation.

You can work around this 'feature' by setting an environment variable: _NO_DEBUG_HEAP=1

This same issue has been driving me nuts for a while; today I found the following, from whence this post is derived: http://blogs.msdn.com/b/larryosterman/archive/2008/09/03/anatomy-of-a-heisenbug.aspx

另外为了更细化的跟踪某个方法的耗时可以在代码中这么写:

    public AdminLayoutAttribute()
{
//TODO: Test
//var userRole = new List<UserRole> { new UserRole { Id = 1, UserId = 1, RoleId = 1 } };
//var user = new User { Id = 1, LoginName = "admin", LoginPwd = "8wdJLK8mokI=", UserRole = userRole };
//SessionHelper.SetSession("CurrentUser", user);
var user = SessionHelper.GetSession("CurrentUser") as User;
if (user != null)
{ // using (StackExchange.Profiling.MiniProfiler.StepStatic("AdminLayout"))
using (MiniProfiler.Current.Step("AdminLayout"))
{
// Enqueue a job
var container = System.Web.HttpContext.Current.Application["Container"] as CompositionContainer;
UserService = container.GetExportedValueOrDefault<IUserService>();
RoleService = container.GetExportedValueOrDefault<IRoleService>();
RoleModulePermissionService = container.GetExportedValueOrDefault<IRoleModulePermissionService>();
ModuleService = container.GetExportedValueOrDefault<IModuleService>();
ModulePermissionService = container.GetExportedValueOrDefault<IModulePermissionService>();
PermissionService = container.GetExportedValueOrDefault<IPermissionService>();
}
}
}

再次访问模块管理时就可以看到AdminLayout的耗时了,好像耗时特别小时这里就不记录

使用MiniProfiler跟踪MVC + EF + Bootstrap 2 权限管理系统的性能消耗

总之有这么一个组件确实可以量化执行过程的耗时。对方法调用次数执行分析更强大的工具还是DotTrace,如图:

使用MiniProfiler跟踪MVC + EF + Bootstrap 2 权限管理系统的性能消耗

参考链接:

MiniProfiler(MiniProfiler.EF6监控调试MVC5和EF6的性能)

解决:MiniProfiler.EF出现System.InvalidOperationException”类型的异常在 EntityFramework.dll 中发生

Entity Framework 4.3. Invalid column name 'CreatedOn'

Miniprofiler breaks on missing CreatedOn column

上一篇:访问修饰符(access modifier)。


下一篇:Java一些常见的出错异常处理