Измерение производительности ASP.NET MVC 3 - PullRequest
11 голосов
/ 28 апреля 2011

Я построил службу JSON в ASP.NET MVC 3 и хочу иметь возможность измерять время выполнения действий в моем приложении (я хочу, чтобы он автоматически регистрировал медленные действия).

Для этого это выглядело великолепно; http://coderjournal.com/2010/10/timing-the-execution-time-of-your-mvc-actions/ (здесь упоминалось и о переполнении стека)

Проблема в том, что я получаю измерения, которые ДОЛЖНЫ быть неверными в этом методе; Я добавил еще один секундомер, который запускает первое в действии и останавливается непосредственно перед возвратом.

Пример:

  • Секундомер внутри метода => 10мс (здесь сериализация с json опущена, поэтому я могу понять, что она короче реальности)
  • Атрибут секундомера (код выше) => 676мс
  • Firefox сообщает, что запрос занял => 70ms .

Я полагаю, что Firefox имеет правильное время здесь (но оно включает в себя загрузку, поэтому оно немного велико), но я хочу понять, почему не работает код атрибута, есть идеи для этого?

Ответы [ 4 ]

16 голосов
/ 28 апреля 2011

Возможно, это не причина того, что он показывает такое длительное время выполнения, но этот атрибут не будет корректно работать с mvc 3, когда у вас есть несколько запросов одновременно.

В предыдущих версиях ASP.NET MVC фильтры действий создавались по запросу, за исключением нескольких случаев.Такое поведение никогда не было гарантированным поведением, а являлось лишь деталью реализации, и контракт на фильтры заключался в том, чтобы считать их не имеющими состояния.В ASP.NET MVC 3 фильтры кэшируются более агрессивно.Поэтому любые фильтры пользовательских действий, которые неправильно хранят состояние экземпляра, могут быть повреждены.

Я бы порекомендовал создать новый секундомер в OnActionExecuting и сохранить его в HttpContext.Current.Items -затем вы можете получить его в OnActionExecuted и распечатать результат.

8 голосов
/ 14 марта 2013

Более правильный подход в дополнение к ответу https://stackoverflow.com/a/5823555/504082 заключается в использовании переопределения OnResultExecuted в конце тактового выполнения. Когда вы вернетесь

ActionResponse.Success(arr.Select(x => func(x)).ToJson();

т.е. какой-то ленивый оператор LINQ в результате вашего действия будет вычислен после действия «выполнено» (выполнение функции «func» не будет учитываться во время выполнения действия). Я получил эту неприятную ошибку и не мог понять, почему мое «время выполнения» действия составляет 100 мс, хотя веб-запрос выполняется 10 секунд. Модифицированный код ниже.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace SW
{
    public class StopwatchAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var stopwatch = new Stopwatch();
            filterContext.HttpContext.Items["Stopwatch"] = stopwatch;

            stopwatch.Start();
        }

        public override void OnResultExecuted(ResultExecutedContext filterContext)
        {
            var stopwatch = (Stopwatch)filterContext.HttpContext.Items["Stopwatch"];
            stopwatch.Stop();

            var httpContext = filterContext.HttpContext;
            var response = httpContext.Response;

            response.AddHeader("X-Runtime", stopwatch.Elapsed.TotalMilliseconds.ToString());
        }
    }
}
1 голос
/ 28 апреля 2011

Почему бы не взглянуть на модуль производительности страницы от Rhino commons?

0 голосов
/ 28 апреля 2011

Похоже, вы выключены на порядок.Вы уверены, что правильно читаете результат?Попробуйте использовать свойство Stopwatch.ElapsedMilliseconds.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...