MiniProfiler 在這個部落格中的很多文章中都有出現過,甚至於也以此為題寫了有四篇的文章:
-
ASP.NET MVC 2 + MiniProfiler 偵測執行效能
-
ASP.NET MVC 3 + MiniProfiler.MVC3 偵測執行效能
-
ASP.NET MVC 2 + MvcPaging + MiniProfiler 連結出現錯誤?
-
Oracle ODAC for Entity Framework + ASP.NET MVC 3 + MiniProfiler.MVC3
哪為什麼現在又要再寫一篇有關 MiniProfiler 的文章呢?
這絕對不是為了要佔篇幅(這裡不是報紙也不是雜誌),也不是為了要騙稿費(我找誰要稿費呀),而是因為 MiniProfiler 在 2012-02-22 所發佈更新的 v2.0 有了蠻多的變革,而我卻是遲至今日才開始想寫這些內容,工作忙碌、twMVC 準備工作滿檔、懶?
總之呢 …… 就看下去吧!
MiniProfiler 發佈之後,受到了很多人的注意,也有很多人導入專案中使用,然而一個工具的出現總是會有很多的不同意見,例如說,我看到一篇高手高來高去的文章討論:
Ayende @ Rahien - Why I don’t like the MVC Mini Profiler codebase
這一篇的討論就來了兩位 MiniProfiler 開發者 Sam Saffron 與 Marc Gravell 的參與,這些討論不像我們在論壇中所看到的戰文。
其實以上的那篇文章內容與後續的討論也讓我明白,並不一定說使用 MiniProfiler 就需要在程式中去加入一些「侵入式」程式碼,例如:使用 using() …. 把要追蹤的程式區段給包覆起來
var profiler = MiniProfiler.Current; // it's ok if this is null
using (profiler.Step("Set page title")){ViewBag.Title = "Home Page";
}using (profiler.Step("Doing complex stuff")){using (profiler.Step("Step A")){ // something more interesting here
Thread.Sleep(100);}using (profiler.Step("Step B")){ // and here
Thread.Sleep(250);}}
其實這樣的包覆方式是為了要突顯某一段程式的執行,然後在顯示區塊中顯示,如下我用我專案的程式來做示範,例如以下的程式,我包覆兩個程式區段,一個是 IQueryable 部分,另一個是直接從資料庫取值,
public ActionResult Test2(string city, string columnName, string sort){using (NorthwindEntities db = new NorthwindEntities()){var profiler = MiniProfiler.Current;using (profiler.Step("Query")){PrepareDropDwonLists(city, columnName, sort);var query = db.Customers.Select(x => x);city = string.IsNullOrWhiteSpace(city) ? "all" : city;if (!city.Equals("all")){query = query.Where("City == @0", city ?? "London");}query = query.OrderBy(string.Format
("{0} {1}",
string.IsNullOrWhiteSpace(columnName) ? "CompanyName" : columnName,string.IsNullOrWhiteSpace(sort) ? "asc" : sort));using (profiler.Step("ToList")){ViewData.Model = query.ToList();}}return View();
}}
在頁面上的顯示視窗就會有這兩個指定突顯的項目,
點選 sql 的連結可以看到詳細的內容,
那如果不使用 using(…) 呢?是否還會在前端頁面的追蹤顯示視窗裡看到這些資訊呢?
public ActionResult Test2(string city, string columnName, string sort){using (NorthwindEntities db = new NorthwindEntities()){PrepareDropDwonLists(city, columnName, sort);var query = db.Customers.Select(x => x);city = string.IsNullOrWhiteSpace(city) ? "all" : city;if (!city.Equals("all")){query = query.Where("City == @0", city ?? "London");}query = query.OrderBy(string.Format(
"{0} {1}",
string.IsNullOrWhiteSpace(columnName) ? "CompanyName" : columnName,string.IsNullOrWhiteSpace(sort) ? "asc" : sort));ViewData.Model = query.ToList();return View();
}}
前端的頁面顯示,還是依然會有追蹤到這個 Action 方法中的 sql 執行內容,只不過就沒有去特別的突顯出來,
所以在不使用 using(…) 把某些程式區段給包覆的情況下,依然可以在前端的追蹤視窗中得到 sql 執行的追蹤內容,只不過如果一個 Action 方法有執行很多的流程步驟的話,就無法清楚地區分出每個流程步驟。
MiniProfiler 2.0.1
回到正題,MiniProfiler 在 2012-02-22 發佈了 2.0 的更新版本,這一個版本在命名空間上就做了很大的改變,這是因為要表示 MiniProfiler 不只是應用在 ASP.NET MVC 上,同樣也有支援 ASP.NET WebFroms 與 WCF 的應用。
MiniProfiler 官網:http://miniprofiler.com/
作者 Sam Saffron 在其部落格中對於 MiniProfiler 2.0 的說明,「Sam Saffron - MiniProfiler 2.0, almost out of the gate」在這篇文章中有詳細說明了 MiniProfiler 2.0 做了哪些的改變,
首先要說明一下命名空間,原本使用 1.9.0 或是 1.9.1 版本的命名空間都會是「MVCMiniProfiler」,
在版本 v2.0.0 以後都將給使用新的命名空間「StackExchange.Profiling」
在程式中建立一個 MiniProfiler instance 還是一樣的方式,
實作
光說不練的話是不行的,雖然之前的文章已經有詳盡的安裝說明了,既然是要寫,就還是把安裝步驟大致交代好了…
Step.1
先準備好一個 ASP.NET MVC 3 的網站專案,並且在這個 MVC 專案中也建立好一個 ADO.NET Entity Framework 的 Model
Step.2
使用 Nuget 逐一安裝以下的套件
- Entity Framework 4.3.1
- jQuery 1.7.2
- MiniProfiler 2.0.1
- MiniProfiler.MVC3 2.0.1
- MiniProfiler.EF 2.0.2
安裝完成後,MiniProfiler 會在我們的專案中增加兩個檔案,
Step.3
修改 View 的 主版頁面「_Layout.cshtml」內容,其實可以照著「_MINIPROFILER_UPDATED_Layout.cshtml」內容來複製貼上,但是 MiniProfiler v.2.0.1 有增加了很多的功能與屬性,所以如果對於 MiniProfiler 比較陌生的朋友還是建議照著以下的方式進行,在最上方的地方加入「StackExchange.Profiling」的引用,然後就是網頁最下面的地方,也就是在 </body> 的上方加上「@MiniProfiler.RenderIncludes()」
之前版本中的「@MiniProfiler.RenderIncludes()」是加在 <body> 的下方,但因為這個方法主要是網頁在 Render 時加入一段 JS 程式,因為顧及到網頁效能的影響,網頁中的 JS 程式以及引用 Javascript 程式檔案都盡量放置在網頁的最下方,如此才不會影響到網頁中各個元素的 Render,好了,以上的步驟都完成之後就可以執行網站專案,來測試看看 MiniProfiler 是否有正確的安裝到專案中,
點開右上角的白色區塊,就會顯示網頁執行的追蹤內容,
再點擊追蹤視窗的「show trivial」還可以顯示更多的執行資訊,
如果是點擊「share」就可以顯示當前追蹤資訊的單一資料頁面,
每一次網頁的執行都有獨立的追蹤資料,所以就可以保留每一次執行的追蹤資料內容,用於程式執行的比對與偵測上有很大的幫助。如果之前有使用過 MiniProifiler 之前版本而還沒有使用過 v2.0.0 之後新版本的人一定會覺得這次需要手動修改程式的地方便少了,而且開啟 Global.asax 之後可以發現,到目前為止的步驟裡,還不必去修改到 Global.asax。
Step.4
現在我們在 HomeController 裡加上一個新的 Action 方法,然後在這個方法增加透過 EF 取得資料的程式,
接著為了要讓 MiniProfiler 可以偵測到 EF 執行的 SQL Command,所以還必須調整「~/App_Start/MiniProfiler.cs」的程式內容,將第 9 ~ 11 行以及第 42 行給解除註解,
修改後就可以執行看結果囉(記得要加入 Index2 的 View 呀!)
執行的網頁顯示結果,
看看所偵測的 EF 執行 SQL Command 內容,
Profiler Popup 調整
基本上,前面四個步驟已經完成的 MiniProfiler 的安裝與使用,那還需要介紹什麼呢?
這裡要介紹調整追蹤資料顯示視窗的方法,調整的地方有兩個地方,一個是在 View 而另一個要在 Global.asax 之中,先來看看在「_Layout.cshtml」的調整,可以在 MiniProfiler.RenderIncludes() 方法中加入參數,
@MiniProfiler.RenderIncludes(position: RenderPosition.Right, showTrivial: false, showTimeWithChildren: false)
看不清楚圖片的,可以另開圖片到新視窗中,會比較清楚,
藉由五個參數的加入,可以調整追蹤視窗的顯示,比較常用到的就三個:position, showTrivial, showTimeWithChildren,看看調整前的追蹤資料顯示視窗,
調整之後,
可以看到追蹤資料顯示視窗由網頁的左上方換到網頁的右上方顯示,原本預設不會顯示的 Time With Children 與 Trivial 資料都變成預設為顯示。
第二種調整的方式就是要在 Global.asax 裡去增加調整的程式,在 Global.asax 中的 Application_Start 方法加入程式,以程式的方式對頁面的追蹤資料顯示視窗做調整,而原本在「_Layout.cshtml」的 MiniProfiler.RederIncludes() 就恢復原狀,
修改後,再一次執行網頁, Time With Children 與 Trilval 資料變回了之前預設的不顯示
MiniProfiler.Settings 還有很多屬性可以做設定,有些比較基本而有些就比較進階,這邊就不多做討論,有興趣的朋友可以自己試試,以下是比較常用的幾個設定屬性,各位可以調整幾個屬性,看看頁面上的 Profile Popup 有什麼不同與改變,
private void InitProfilerSettings(){MiniProfiler.Settings.PopupRenderPosition = RenderPosition.Right; //defaults to left
MiniProfiler.Settings.PopupMaxTracesToShow = 20; //defaults to 15
MiniProfiler.Settings.RouteBasePath = "~/profiler"; //e.g. /profiler/mini-profiler-includes.jsMiniProfiler.Settings.StackMaxLength = 256; // default is 120 characters
MiniProfiler.Settings.PopupShowTrivial = true;
MiniProfiler.Settings.PopupShowTimeWithChildren = true;
}
先寫到這裡為止,其實還有很多新增的功能可以介紹給大家,但也不需要一次就全部塞給大家,一次全給,也未必能夠消化,如果大家不想等我下一篇的進階介紹或是想要自己研究,建議各位可以到前面有介紹過的,MiniProfiler 作者所寫的文章「Sam Saffron - MiniProfiler 2.0, almost out of the gate」,而如果想要知道這個 MiniProfiler 的結構與原始碼內容,則是可以到官網上下載或是 github 下載,
github - https://github.com/SamSaffron/MiniProfiler
如果對於 MiniProfiler 使用上有任何的問題,則是可以到 MiniProfiler 的討論區中發問,
http://community.miniprofiler.com/
或者也可以到 stackoverflow 中查看有關「mini-profiler」Tag 的提問與解答內容
http://stackoverflow.com/questions/tagged/mini-profiler
以上
您好
回覆刪除今天按照文章實作時發現到
"然後就是網頁最下面的地方,也就是在 /body 的上方加上「@MiniProfiler.RederIncludes()」"
打錯了
@MiniProfiler.RenderIncludes()
才對
感謝您寫這文章教學
謝謝你提出錯誤的地方,已經修正了。
刪除