In the recent article, Code Sample: TimeMeasureTest, I showed how to perform time measuring related operations with the static TimeMeasure class. Moving to ASP.NET Core MVC, I have included two ways to perform the same operation on your Controller methods; one by using TimeMeasureAttribute explicitly or by using a TimeMeasuringFilter in general.

The former approach is great if you suspect a method to be slow and just want a simple way to time measure the code; the latter is for more instrumentation minded usage, where you might setup a threshold and store the result for application insight.

Instrumentation

Common for both approaches is, that somewhere in your configuration (most likely the Startup class) you assign a callback method to the TimeMeasure.CompletedCallback delegate. I simply used a lamda expression: profiler => Trace.WriteLine(profiler.ToString());

The first example uses the TimeMeasureAttribute approach. You simply decorate one or more methods that you want insights for. Optionally, you can configure the attribute with a threshold. For instance, if you only want to trigger a callback when a method takes longer than 1 second, you would decorate the attribute like this: [TimeMeasure(1, TimeUnit.Seconds)].

using System;  
using Cuemon.AspNetCore.Mvc;  
using Cuemon.AspNetCore.Mvc.Filters;  
using Cuemon.Integrity;  
using Microsoft.AspNetCore.Mvc;

namespace Cuemon.Core.Examples  
{
    public class TimeSpanController : Controller
    {
        [TimeMeasure]
        [HttpHead]
        [HttpGet]
        [Route("{hours}/{minutes}/{seconds}")]
        public IActionResult GetTimeSpan(int hours, int minutes, int seconds)
        {
            return this.OkOrNotModified(new TimeSpan(hours, minutes, seconds), ts => CacheValidator.ReferencePoint.CombineWith(ts.Ticks));
        }
    }
}

When the method is called 5 times, it produces this result:

TimeMesaureAttribute Result

The other example is the general approach, and for simplicity I only included what isolated needs to be done in the ConfigureServices method. Optionally you can provide an options delegate that has three properties; TimeMeasureCompletedThreshold, MethodDescriptor and RuntimeParameters. The most important is the TimeMeasureCompletedThreshold. The other two are for advanced scenarios.

using Cuemon.AspNetCore.Mvc.Filters;  
using Microsoft.Extensions.DependencyInjection;

namespace Cuemon.Core.Examples  
{
    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(o => o.Filters.Add(new TimeMeasuringFilter()));
        }
    }
}

Thats it .. same result as the first example, but will cover all controller related methods using ActionExecutingContext.

As always; I hope you have enjoyed reading this article - HAPPY CODING!