• 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         });

    这样就比较完美了

  • 相关阅读:
    存储过程访问外部服务器
    MVC4 code first 增加属性,对应自动修改列的方法笔记
    摘抄
    一条命令使win7可以直接运行.net3.5程序
    工作心得
    删除一个不存在的东西可以抛出异常吗
    洛谷P3379 【模板】最近公共祖先(LCA)
    洛谷P1967 货车运输
    洛谷P1653 猴子
    洛谷P2278 [HNOI2003]操作系统
  • 原文地址:https://www.cnblogs.com/zhouxiuquan/p/3768136.html
Copyright © 2020-2023  润新知