2011-04-28 31 views
10

我在ASP.NET MVC 3中構建了一個JSON服務,我希望能夠測量我的應用程序中的動作的執行時間(我希望它能夠自動記錄慢速動作)。測量ASP.NET MVC的性能3

因此,這看起來不錯; http://coderjournal.com/2010/10/timing-the-execution-time-of-your-mvc-actions/(這裏也提到了堆棧溢出的地方)

問題是我得到的測量結果必須是錯誤的, 我已經添加了另一個秒錶,開始第一件事的行動,並在返回之前停止。

實施例:

  • 秒錶方法內=>10ms的(串行化到JSON在此省略,所以可以理解,它比實際短)
  • 秒錶屬性(上面的代碼)= >676ms
  • 火狐說,要求把=>70ms的

我相信firefox在這裏有正確的時間(但它包括下載,所以它有點大),但我想明白爲什麼屬性代碼不起作用,對此有什麼想法?

+0

是啊,緩存關閉在Firefox ... – ullmark 2011-04-28 15:52:42

回答

16

這可能不是它顯示長執行時間的原因,但是當您一次有多個請求時,該屬性將無法正確使用mvc 3。

在ASP.NET MVC的早期版本中, 行動過濾器是每個請求 創建除了在少數情況下。此行爲 從來沒有保證的行爲,但 只是一個實現細節和 過濾器的合同是 認爲它們是無狀態的。在ASP.NETMVC 3中,積極地緩存更多的過濾器。因此,任何不正確地存儲 實例狀態的自定義 操作篩選器可能會中斷。

我建議在OnActionExecutingsave it to HttpContext.Current.Items實例化新的秒錶 - 那麼您可以在OnActionExecuted檢索並打印出結果。

+0

你是正確的,因爲動作被緩存,構造函數僅在一段時間,所以同樣的秒錶被重用運行一次。 – ullmark 2011-05-02 08:05:06

+0

偉大的觀點! – Ricky 2011-06-27 06:48:21

+1

有問題的代碼[已更新](https://github.com/managedfusion/managedfusion-web/blob/master/src/Web/Mvc/StopwatchAttribute.cs),現在按照LukášNovotný的建議工作。 – 2012-05-20 00:59:41

8

除了回答https://stackoverflow.com/a/5823555/504082之外,更正確的方法是在時鐘執行結束時使用OnResultExecuted覆蓋。 當您返回

ActionResponse.Success(arr.Select(x => func(x)).ToJson(); 

即有些慵懶LINQ語句作爲你的行爲的結果,它會被計算被「執行」行動(函數「功能」的執行不會對動作執行時間算) 。 我有這個討厭的錯誤,不知道爲什麼我的行動「執行時間」是100毫秒,雖然Web請求執行10秒。下面修改的代碼。

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Linq; 
using System.Web; 
using System.Web.Mvc; 

namespace SW 
{ 
    public class StopwatchAttribute : ActionFilterAttribute 
    { 
     public override void OnActionExecuting(ActionExecutingContext filterContext) 
     { 
      var stopwatch = new Stopwatch(); 
      filterContext.HttpContext.Items["Stopwatch"] = stopwatch; 

      stopwatch.Start(); 
     } 

     public override void OnResultExecuted(ResultExecutedContext filterContext) 
     { 
      var stopwatch = (Stopwatch)filterContext.HttpContext.Items["Stopwatch"]; 
      stopwatch.Stop(); 

      var httpContext = filterContext.HttpContext; 
      var response = httpContext.Response; 

      response.AddHeader("X-Runtime", stopwatch.Elapsed.TotalMilliseconds.ToString()); 
     } 
    } 
} 
+0

Ermagherd,這太棒了。你知道是否可以將它與'ActionFilterAttribute'分開,以便它可以用於任何方法?我想我只是爲該屬性設置一個名稱屬性來跟蹤各種秒錶或記錄一個並在EndRequest中殺死它,但我無法弄清楚如何爲非操作獲取「OnResultExecuted」事件。 – Nenotlep 2013-04-29 10:05:01

+0

如果你想在網頁上有一個「調試」控制檯 – 2013-09-11 17:24:36