页面生成时间 - ASP.Net MVC

时间:2022-06-26 03:24:41

I'm looking for a way to track how long it took for a page to be generated by the server. I know I can use Trace to track this but I need a way to display this per page.

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

Its ASP.Net MVC 2

其ASP.Net MVC 2

3 个解决方案

#1


14  

Yep the Derin Suggestion is the standard Way to do it in an ASP.NEt application, i would just suggest add an if so it does not interfere with non-HTML responses: EDIT: added complete implementation

是的,Derin Suggestion是在ASP.NEt应用程序中执行它的标准方法,我建议添加一个if 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 */ }
}

you can also add some style to it...

你也可以添加一些风格......

And remember to register your Module in WebConfig inside httpModules Section:

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

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

For a Complete Reference about this check the Pro ASP.NET MVC Framework by Steven Sanderson - Chapter 15 - Performance, Monitoring Page Generation Times.

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

EDIT:(comment @Pino) Here is the example for my project: alt text http://www.diarioplus.com/files/pictures/example_performance.JPG

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

#2


15  

You can implement it like a ActionFilterAttribute

您可以像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;
    }
}

Decorate every controller or action-method with it and voila, it spit outs the text in debug.

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

EDIT: If you want to print it on the page you could add this snippet to the OnActionExecuted method

编辑:如果要在页面上打印它,您可以将此片段添加到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
}

Now you have the executiontime saved in ViewData and can access it in the page.. I usually put it in the masterpage like this

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

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

#3


4  

It will depend on where you want to include this information. For example you could write an http handler that will display the render time after the </html> tag:

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

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()
    {
    }
}

If you want to display render time somewhere in the middle of the html page then this render time will not account for the total page render time.

如果要在html页面的中间某处显示渲染时间,则此渲染时间不会占总页面渲染时间。

#1


14  

Yep the Derin Suggestion is the standard Way to do it in an ASP.NEt application, i would just suggest add an if so it does not interfere with non-HTML responses: EDIT: added complete implementation

是的,Derin Suggestion是在ASP.NEt应用程序中执行它的标准方法,我建议添加一个if 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 */ }
}

you can also add some style to it...

你也可以添加一些风格......

And remember to register your Module in WebConfig inside httpModules Section:

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

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

For a Complete Reference about this check the Pro ASP.NET MVC Framework by Steven Sanderson - Chapter 15 - Performance, Monitoring Page Generation Times.

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

EDIT:(comment @Pino) Here is the example for my project: alt text http://www.diarioplus.com/files/pictures/example_performance.JPG

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

#2


15  

You can implement it like a ActionFilterAttribute

您可以像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;
    }
}

Decorate every controller or action-method with it and voila, it spit outs the text in debug.

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

EDIT: If you want to print it on the page you could add this snippet to the OnActionExecuted method

编辑:如果要在页面上打印它,您可以将此片段添加到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
}

Now you have the executiontime saved in ViewData and can access it in the page.. I usually put it in the masterpage like this

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

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

#3


4  

It will depend on where you want to include this information. For example you could write an http handler that will display the render time after the </html> tag:

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

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()
    {
    }
}

If you want to display render time somewhere in the middle of the html page then this render time will not account for the total page render time.

如果要在html页面的中间某处显示渲染时间,则此渲染时间不会占总页面渲染时间。