MVC 实现计算页面执行时间

使用 ActionFilterAttribute 来实现:

 1 public class PerformanceActionAttribute:ActionFilterAttribute
 2     {
 3         public string Message { get; set; }
 4 
 5 
 6         public override void OnActionExecuting(ActionExecutingContext filterContext)
 7         {
 8             //在Action执行前执行            
 9 
10             GetTimer(filterContext, "action").Start();
11 
12             base.OnActionExecuting(filterContext);
13         }
14 
15         public override void OnActionExecuted(ActionExecutedContext filterContext)
16         {
17             //在Action执行之后执行
18             var actionTimer = GetTimer(filterContext, "action");
19             //GetTimer(filterContext, "action").Stop();
20             actionTimer.Stop();
21             base.OnActionExecuted(filterContext);
22             string extime = "页面执行耗时" + actionTimer.ElapsedMilliseconds+"毫秒";
23             filterContext.HttpContext.Response.Headers.Add("extime",extime);
24             //在这里显示给用户的时间只是action的执行时间,如果在view中有执行调用代码的部分,则时间不会
25             //记录在内,所以这里的时间不是很准,但是这个时间可以很自由的被view中的代码调用显示,使得界面可以按照
26             //自己的意愿进行显示
27         }
28 
29 
30         public override void OnResultExecuting(ResultExecutingContext filterContext)
31         {
32             GetTimer(filterContext, "render").Start();
33 
34             base.OnResultExecuting(filterContext);
35         }
36 
37         public override void OnResultExecuted(ResultExecutedContext filterContext)
38         {
39             //在Result执行之后            
40             //这里使用response.write输出只能是输出到documnet的最后部分,不能按照想法显示到指定的随意位置
41             //所以这里隐藏显示了。
42             //这这部分使用response.Headers是无效的,因为当执行这部分内容的时候,view已经渲染完了,在这添加到Header
43             //中的值,无法在页面获得
44             var renderTimer = GetTimer(filterContext, "render");
45             renderTimer.Stop();
46 
47             var actionTimer = GetTimer(filterContext, "action");
48             var response = filterContext.HttpContext.Response;
49 
50             if (response.ContentType == "text/html")
51             {
52                 response.Write(
53                     String.Format(
54                         "<p id='pidtimeelapse' style='display:none;'>Action '{0} :: {1}', Execute: {2}ms, Render: {3}ms.</p>",
55                         filterContext.RouteData.Values["controller"],
56                         filterContext.RouteData.Values["action"],
57                         actionTimer.ElapsedMilliseconds,
58                         renderTimer.ElapsedMilliseconds
59                     )
60                 );
61                 
62             }
63 
64             base.OnResultExecuted(filterContext);
65         }
66 
67        
68 
69         private Stopwatch GetTimer(ControllerContext context, string name)
70         {
71             string key = "__timer__" + name;
72             if (context.HttpContext.Items.Contains(key))
73             {
74                 return (Stopwatch)context.HttpContext.Items[key];
75             }
76 
77             var result = new Stopwatch();
78             context.HttpContext.Items[key] = result;
79             return result;
80         }
81     }

 

在action 处使用 见第一行

 1 [PerformanceAction]
 2         public ActionResult Index(string type="默认",int pageIndex=1)
 3         {
 4             string orderType = type;            
 5             int pageSize = pageSizeCom;
 6             int total = 1;
 7             List<vArticleMain> list = artBLL.GetArticleByPage(pageIndex, pageSize, orderType, out total);
 8             ViewBag.list = list;
 9 
10             //分页信息            
11 
12             ViewBag.pageIndex = pageIndex;
13             ViewBag.pageCount = total;
14             ViewBag.type = type;
15 
16             return View();            
17         }

在view 中显示 可以在指定位置引用

            <div class="row col-md-12">
                @Response.Headers.Get("extime")
            </div>

 

还有一种是使用 httpmodule的方法,使用该方法不用在每个action上加特性了

地址:http://haacked.com/archive/2008/07/02/httpmodule-for-timing-requests.aspx/

但是在使用该方法调试的时候,出现一个进程中有多个线程的情况,该方法多次执行。而时间编程是单线程的,没有定义多线程,不知道为什么会出现多线程情况。

所以没有使用该方法。(该方法得到的时间比filter的方法得到的时间要更准确)

filter方法参考链接:http://bradwilson.typepad.com/blog/2010/07/aspnet-mvc-filters-and-statefulness.html

                         http://www.sharejs.com/codes/csharp/6235

                          http://blog.csdn.net/keepitshortandsimple/article/details/7357954

 

 

第二天想到新的解决办法,思路就是:OnResultExecuted 中最后输出的代码虽然不在服务器端的view中用response取得,只能输出到页面的最后部分,

但是当信息传输到浏览器上的时候,可以用jquery 来取得输出的内容,然后显示到指定的位置。OnResultExecuted 方法只是在view页面在服务器端渲染完之后执行,

不是在浏览器上显示完之后执行,所以可以在浏览器上取得在OnResultExecuted 阶段输出的内容。

attribute的代码 :在 OnActionExecuted 阶段不再输出内容

 1 public class PerformanceActionAttribute:ActionFilterAttribute
 2     {
 3         public string Message { get; set; }
 4 
 5 
 6         public override void OnActionExecuting(ActionExecutingContext filterContext)
 7         {
 8             //在Action执行前执行            
 9 
10             GetTimer(filterContext, "action").Start();
11 
12             base.OnActionExecuting(filterContext);
13         }
14 
15         public override void OnActionExecuted(ActionExecutedContext filterContext)
16         {
17             //在Action执行之后执行
18             //var actionTimer = GetTimer(filterContext, "action");
19             GetTimer(filterContext, "action").Stop();
20             //actionTimer.Stop();
21             base.OnActionExecuted(filterContext);
22             //string extime = "页面执行耗时" + actionTimer.ElapsedMilliseconds+"毫秒";
23             //filterContext.HttpContext.Response.Headers.Add("extime",extime);
24 
25             //在这里显示给用户的时间只是action的执行时间,如果在view中有执行调用代码的部分,则时间不会
26             //记录在内,所以这里的时间不是很准,但是这个时间可以很自由的被view中的代码调用显示,使得界面可以按照
27             //自己的意愿进行显示
28 
29             //想出新的办法了,所以这里注释掉,用下边的总时间
30         }
31 
32 
33         public override void OnResultExecuting(ResultExecutingContext filterContext)
34         {
35             GetTimer(filterContext, "render").Start();
36 
37             base.OnResultExecuting(filterContext);
38         }
39 
40         public override void OnResultExecuted(ResultExecutedContext filterContext)
41         {
42             //在Result执行之后            
43             //这里使用response.write输出只能是输出到documnet的最后部分,不能按照想法显示到指定的随意位置
44             //所以这里隐藏显示了。
45             //这这部分使用response.Headers是无效的,因为当执行这部分内容的时候,view已经渲染完了,在这添加到Header
46             //中的值,无法在页面获得
47 
48             //第二天想出新的方法来解决
49             //如下所以,输出到页面的内容放到固定标签中,有ID,然后再页面上用js来取得对应的内容,然后相加,显示到指定的位置
50             var renderTimer = GetTimer(filterContext, "render");
51             renderTimer.Stop();
52 
53             var actionTimer = GetTimer(filterContext, "action");
54             var response = filterContext.HttpContext.Response;
55 
56             if (response.ContentType == "text/html")
57             {
58                 response.Write(
59                     String.Format(
60                         "<p id='disAction' style='display:block;'>Action '{0} :: {1}' <span id='disexecute'>{2}</span><span id='disrender'>{3}</span></p>",
61                         filterContext.RouteData.Values["controller"],
62                         filterContext.RouteData.Values["action"],
63                         actionTimer.ElapsedMilliseconds,
64                         renderTimer.ElapsedMilliseconds
65                     )
66                 );
67                 
68             }
69 
70             base.OnResultExecuted(filterContext);
71         }
72 
73        
74 
75         private Stopwatch GetTimer(ControllerContext context, string name)
76         {
77             string key = "__timer__" + name;
78             if (context.HttpContext.Items.Contains(key))
79             {
80                 return (Stopwatch)context.HttpContext.Items[key];
81             }
82 
83             var result = new Stopwatch();
84             context.HttpContext.Items[key] = result;
85             return result;
86         }
87     }

在controller中的内容不变,

在view中的内容:

1  <div id="pagetime" class="row col-md-12">
2                
3   </div>

jquery

1  $(function () {            
2             var disexecute = $("#disexecute").html();
3             var disrender = $("#disrender").html();
4             var ht = "页面执行耗时" + (parseInt(disexecute) + parseInt(disrender)) + "毫秒";
5             $("#pagetime").html(ht);
6         });

这样就比较完美了

 

 

posted @ 2014-06-04 16:23  百年俊少  阅读(1090)  评论(0编辑  收藏  举报