Подтвердить что ты не робот

Измерение времени, вызывающего действия ASP.NET MVC Controller

Некоторые пользователи приложения MVC 4 испытывают спорадическую медлительность. Предположительно, не каждый пользователь сообщает об этой проблеме каждый раз, когда это происходит с ними.

Моя мысль состоит в том, чтобы измерить время, затрачиваемое на каждое действие контроллера, и данные журнала о действиях, которые превышают установленное время, чтобы облегчить дальнейший анализ (чтобы разрешить или исключить проблему с сервером/кодом).

Есть ли удобный способ подключиться для выполнения таких измерений, чтобы я мог избежать добавления кода к каждому действию? В настоящее время я не использую IOC для этого проекта и не стесняюсь представить его только для решения этой проблемы.

Есть ли лучший способ решить эту проблему?

4b9b3361

Ответ 1

Не удалось создать глобальный фильтр действий? Что-то вроде этого:

public class PerformanceTestFilter : IActionFilter
{
    private Stopwatch stopWatch = new Stopwatch();

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        stopWatch.Reset();
        stopWatch.Start();
    }

    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        stopWatch.Stop();
        var executionTime = stopWatch.ElapsedMilliseconds;
        // Do something with the executionTime
    }
}

а затем добавьте его в коллекцию GlobalFilters в `Application_Start() '

GlobalFilters.Filters.Add(new PerformanceTestFilter());

Вы можете получить подробную информацию о тестируемом контроллере из параметра filterContext.

UPDATE

Добавление фильтра в коллекцию GlobalFilters напрямую создаст один экземпляр фильтра для всех действий. Это, конечно, не будет работать для одновременного согласования запросов. Чтобы создать новый экземпляр для каждого действия, создайте поставщика фильтра:

public class PerformanceTestFilterProvider : IFilterProvider
{
    public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
    {
        return new[] {new Filter(new PerformanceTestFilter(), FilterScope.Global, 0)};
    }
}

Затем вместо добавления фильтра напрямую добавьте поставщика фильтра в Application_Start():

FilterProviders.Providers.Add(new PerformanceTestFilterProvider());

Ответ 2

Я обычно добавляю этот простой код в нижнюю часть моего представления макета:

<!-- Page generated in @((DateTime.UtcNow - HttpContext.Current.Timestamp.ToUniversalTime()).TotalSeconds.ToString("F4")) s -->

Выводит что-то вроде:

<!-- Page generated in 0.4399 s -->

Это начинает отсчет, когда создается HttpContext (в соответствии с документация) и останавливается прямо перед записью на вывод, поэтому должен быть довольно точным.

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

Для более продвинутой диагностики я использовал Glimpse.

Ответ 3

Попробуйте ASP.NET 4.5 Инструментарий страницы

Это инструмент рендеринга страницы: время вашего приложения может быть потрачено на контроллер, но есть много раз, когда он проводится в viewrendering. Особенно, если у вас много партикулов и html-помощников.

Ответ 4

Обновление - установите мой пакет NuGet с секундомером с Install-Package StopWatch см. Профиль и время вашего приложения ASP.NET MVC до Azure

См. мой учебник Использование асинхронных методов в ASP.NET MVC 4 который имеет глобальный таймер фильтра действий. Вы можете использовать ELMAH для регистрации данных. Мой образец My sample http://msdn.microsoft.com/en-us/library/gg416513(v=vs.98) также имеет тот же фильтр синхронизации и проще, но он пред-Razor.

Найдите атрибут секундомера, чтобы включить синхронизацию.

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new HandleErrorAttribute());
        filters.Add(new UseStopwatchAttribute());
    }
}