【问题标题】:Page generation time - ASP.Net MVC页面生成时间 - ASP.Net MVC
【发布时间】:2009-12-01 14:48:34
【问题描述】:

我正在寻找一种方法来跟踪服务器生成页面所用的时间。我知道我可以使用 Trace 来跟踪它,但我需要一种方法来显示每页。

它的 ASP.Net MVC 2

【问题讨论】:

    标签: asp.net asp.net-mvc


    【解决方案1】:

    你可以像 ActionFilterAttribute 一样实现它

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public class LoggingAttribute : ActionFilterAttribute
    {
        private readonly Stopwatch _sw;
    
        public LoggingAttribute()
        {
            _sw = new Stopwatch();
        }
    
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            _sw.Start();
            Debug.WriteLine("Beginning executing: " + GetControllerAndActionName(filterContext.ActionDescriptor));
        }
    
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            _sw.Stop();
            var ms = _sw.ElapsedMilliseconds;
    
            Debug.WriteLine("Finishing executing: " + GetControllerAndActionName(filterContext.ActionDescriptor));
            Debug.WriteLine("Time elapsed: "+ TimeSpan.FromMilliseconds(ms).TotalSeconds);
        }
    
        private string GetControllerAndActionName(ActionDescriptor actionDescriptor)
        {
            return actionDescriptor.ControllerDescriptor.ControllerName + " - " + actionDescriptor.ActionName;
        }
    }
    

    用它装饰每个控制器或动作方法,瞧,它会在调试中吐出文本。

    编辑:如果你想在页面上打印它,你可以将这个 sn-p 添加到 OnActionExecuted 方法中

    if(filterContext.Result is ViewResult) { //Make sure the request is a ViewResult, ie. a page
      ((ViewResult) filterContext.Result).ViewData["ExecutionTime"] = ms; //Set the viewdata dictionary
    }
    

    现在你已经将执行时间保存在 ViewData 中,并且可以在页面中访问它。我通常这样放在母版页中

    <!-- The page took <%= ViewData["ExecutionTime"] %> ms to execute -->
    

    【讨论】:

    • 装饰每个控制器或动作方法有点麻烦,因为我们有很多(相当大的项目) - 无论如何我们可以在不做如此大的改变的情况下扩大这个工作站点?
    • 在我的项目中,我所有的控制器都继承自 BaseController。所以我只是装饰了基础控制器,它反过来“装饰”了所有正在执行的动作方法。
    • 它的方法非常好,值得一提的是,它实际上跟踪的是控制器的生命周期,而不是总的请求生命周期。
    • @Pino - 使用 ASP.NET MVC3,您可以在 Application_Start 处理程序期间将属性添加到 GlobalFiltersCollection 以避免用它装饰每个类/动作。
    • 不应该用 OnResultExecuted 而不是 OnActionExecuted 计算经过的时间吗?
    【解决方案2】:

    是的,Derin Suggestion 是在 ASP.NET 应用程序中执行此操作的标准方式,我只建议添加一个 if,这样它就不会干扰非 HTML 响应: 编辑:添加了完整的实现

    public class PerformanceMonitorModule : IHttpModule
    {
    
        public void Init(HttpApplication context)
        {
            context.PreRequestHandlerExecute += delegate(object sender, EventArgs e)
            {
                //Set Page Timer Star
                HttpContext requestContext = ((HttpApplication)sender).Context;
                Stopwatch timer = new Stopwatch();
                requestContext.Items["Timer"] = timer;
                timer.Start();
                 };
            context.PostRequestHandlerExecute += delegate(object sender, EventArgs e)
            {
    
                HttpContext httpContext = ((HttpApplication)sender).Context;
                HttpResponse response = httpContext.Response;
                Stopwatch timer = (Stopwatch)httpContext.Items["Timer"];
                timer.Stop();
    
                // Don't interfere with non-HTML responses
                if (response.ContentType == "text/html")
                {
                    double seconds = (double)timer.ElapsedTicks / Stopwatch.Frequency;
                    string result_time = string.Format("{0:F4} sec ", seconds);
                    RenderQueriesToResponse(response,result_time);
                }
            };
        }
        void RenderQueriesToResponse(HttpResponse response, string result_time)
        {
            response.Write("<div style=\"margin: 5px; background-color: #FFFF00\"");
            response.Write(string.Format("<b>Page Generated in "+ result_time));
            response.Write("</div>");
        }
        public void Dispose() { /* Not needed */ }
    }
    

    你也可以给它添加一些样式...

    记得在 httpModules 部分的 WebConfig 中注册您的模块:

      <add name="Name" type="namespace, dll"/>
    

    有关此内容的完整参考,请查看 Steven Sanderson 编写的 Pro ASP.NET MVC 框架 - 第 15 章 - 性能,监控页面生成时间。

    编辑:(评论@Pino) 这是我的项目的示例: alt text http://www.diarioplus.com/files/pictures/example_performance.JPG

    【讨论】:

    • 谢谢 - 效果很好,除了这似乎在
    【解决方案3】:

    这取决于您希望在何处包含此信息。例如,您可以编写一个 http 处理程序,它将在 &lt;/html&gt; 标记之后显示渲染时间:

    public class RenderTimeModule : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            context.BeginRequest += (sender, e) =>
            {
                var watch = new Stopwatch();
                var app = (HttpApplication)sender;
                app.Context.Items["Stopwatch"] = watch;
                watch.Start();
            };
    
            context.EndRequest += (sender, e) =>
            {
                var app = (HttpApplication)sender;
                var watch = (Stopwatch)app.Context.Items["Stopwatch"];
                watch.Stop();
                var ts = watch.Elapsed;
                string elapsedTime = String.Format("{0} ms", ts.TotalMilliseconds);
                app.Context.Response.Write(elapsedTime);
            };
        }
    
        public void Dispose()
        {
        }
    }
    

    如果你想在 html 页面中间的某个地方显示渲染时间,那么这个渲染时间将不考虑总的页面渲染时间。

    【讨论】:

    • 这似乎是在破坏我的页面的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-13
    • 1970-01-01
    相关资源
    最近更新 更多