Измерение производительности ASP.NET MVC 3

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

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

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

Пример:

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

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

Ответ 1

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

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

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

Ответ 2

Более правильный подход в дополнение к ответу fooobar.com/questions/520288/... заключается в использовании переопределения 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());
        }
    }
}

Ответ 4

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