Время генерации страниц - ASP.NET MVC

Наконец блоки разрешают Вам, как разработчик, убираться после себя, независимо от действий предыдущего кода в попытке {}, блок встретился с ошибками, и сделайте, чтобы другие указали на это, главным образом подпадает под защиту освобождения ресурсов - заключительные указатели / сокеты / наборы результатов, возвращая соединения с пулом и т.д.

, @mats очень корректен, что всегда существует потенциал для "твердых" отказов - наконец, блоки не должны включать код в жестком реальном времени, который должен всегда делаться транзакционно в попытке {}

@mats снова - реальная красота состоит в том, что это позволяет Вам, выдают исключения назад из Ваших собственных методов, и все еще гарантируют, что Вы убираетесь:

try
{
StreamReader stream = new StreamReader("foo.bar");
mySendSomethingToStream(stream);
}
catch(noSomethingToSendException e) {
    //Swallow this    
    logger.error(e.getMessage());
}
catch(anotherTypeOfException e) {
    //More serious, throw this one back
    throw(e);
}
finally
{
stream.close();
}

Так, мы можем поймать много типов исключения, обработать их по-другому (первое позволяет выполнение для чего-либо вне попытки {}, второе эффективно возвращается), но всегда аккуратно, и аккуратно разрешите.

15
задан LiamB 1 December 2009 в 14:48
поделиться

3 ответа

Да, предложение Derin - это стандартный способ сделать это в приложении 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 */ }
}

, вы также можете добавить к нему некоторый стиль ...

И не забудьте зарегистрировать свой модуль в WebConfig в разделе httpModules:

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

Для получения полной справки об этом проверьте Pro ASP.NET MVC Framework Стивена Сандерсона - Глава 15 - Производительность, мониторинг времени генерации страницы.

РЕДАКТИРОВАТЬ: (комментарий @Pino) Вот пример моего проекта: альтернативный текст http://www.diarioplus.com/files/pictures/example_performance.JPG

14
ответ дан 1 December 2019 в 01:45
поделиться

Вы можете реализовать это как 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;
    }
}

Украсить им каждый контроллер или метод действия и вуаля, он выдаст текст при отладке.

РЕДАКТИРОВАТЬ: Если вы хотите распечатать его на странице вы можете добавить этот фрагмент к методу 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 -->
15
ответ дан 1 December 2019 в 01:45
поделиться

Это будет зависеть от того, куда вы хотите включить эту информацию. Например, вы можете написать обработчик 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()
    {
    }
}

Если вы хотите отображать время рендеринга где-то в середине страницы html, тогда это время рендеринга не будет учитывать общее время отображения страницы.

4
ответ дан 1 December 2019 в 01:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: