How to count await method execution time - c#

I am working on a dot net core project. In which I have to count how much had taken by my await method while executing.
[HttpPost]
public async Task<bool> InsertIntoDatabase([Frombody] StudentModel objStu) {
//For Each method and other stuff
await DoInsert(Fiels Details);
}
I am calling this method in Ajax. So after successful execution of code, I want to return the number of times in minutes taken by the method.
This insertion process contains 500+ records. So, I am interested to calculate the time

One approach is to use Stopwatch
[HttpPost]
public async Task<bool> InsertIntoDatabase([Frombody] StudentModel student)
{
var clock = new Stopwatch();
clock.Start();
await DoInsert(student);
clock.Stop();
var minutes = clock.Elapsed.TotalMinutes();
}
Stopwatch Class

Why not return a custom object in your task with the time and the result?
private async Task<MyClass> GetResult()
{}
public class MyClass
{
public bool Success { get; set; }
public long TimeInSeconds { get; set; }
}

I would highly recommend checking out MiniProfiler.
It's extremely easy to setup!
Install MiniProfiler via Nuget
Add the MiniProfiler tag helper to your _Layout.cshtml
Add the MiniProfiler tag (<mini-profiler />) to your HTML (I put mine in Layout.cshtml as well)
Add to services in Startup.cs:
services.AddMiniProfiler(options =>
{
options.RouteBasePath = "/profiler";
options.SqlFormatter = new SqlServerFormatter();
});
Add this AFTER calling app.UseStaticFiles():
if (env.IsDevelopment())
{
app.UseMiniProfiler();
}
Now MiniProfiler is ready to go and will only appear in development (step 5). To profile some code do:
using (MiniProfiler.Current.Step("This Will be the label displayed on the front end"))
{
//code you want to profile
}
Now run your code and voila! MiniProfiler will put a very small table on your page (I THINK it defaults top left). Each row is the elapsed of the request (works with AJAX too!).

Related

How to efficiently count HTTP Calls in asp.net core?

I have an abstract class called HttpHelper it has basic methods like, GET, POST, PATCH, PUT
What I need to achieve is this:
Store the url, time & date in the database each time the function is called GET, POST, PATCH, PUT
I don't want to store directly to the database each time the functions are called (that would be slow) but to put it somewhere (like a static queue-memory-cache) which must be faster and non blocking, and have a background long running process that will look into this cache-storage-like which will then store the values in the database.
I have no clear idea how to do this but the main purpose of doing so is to take the count of each calls per hour or day, by domain, resource and url query.
I'm thinking if I could do the following:
Create a static class which uses ConcurrentQueue<T> to store data and call that class in each function inside HttpHelper class
Create a background task similar to this: Asp.Net core long running/background task
Or use Hangfire, but that might be too much for simple task
Or is there a built-in method for this in .netcore?
Both Hangfire and background tasks would do the trick as consumers of the queue items.
Hangfire was there before long running background tasks (pre .net core), so go with the long running tasks for net core implementations.
There is a but here though.
How important is to you that you will not miss a call? If it is, then neither can help you.
The Queue or whatever static construct you have will be deleted the time your application crashes/machine restarts or just plain recycling of the application pools.
You need to consider some kind of external Queuing mechanism like rabbit mq with persistence on.
You can also append to a file, but that might also cause some delays as read/write.
I do not know how complex your problem is but I would consider two solutions.
First is calling Async Insert Method which will not block your main thread but will start task. You can return response without waiting for your log to be appended to database. Since you want it to be implemented in only some methods, I would do it using Attributes and Middleware.
Simplified example:
public IActionResult SomePostMethod()
{
LogActionAsync("This Is Post Method");
return StatusCode(201);
}
public static Task LogActionAsync(string someParameter)
{
return Task.Run(() => {
// Communicate with database (X ms)
});
}
Better solution is creating buffer which will not communicate with database each time but only when filled or at interval. It would look like this:
public IActionResult SomePostMethod()
{
APILog.Log(new APILog.Item() { Date = DateTime.Now, Item1 = "Something" });
return StatusCode(201);
}
public partial class APILog
{
private static List<APILog.Item> _buffer = null;
private cont int _msTimeout = 60000; // Timeout between updates
private static object _updateLock = new object();
static APILog()
{
StartDBUpdateLoopAsync();
}
private void StartDBUpdateLoopAsync()
{
// check if it has been already and other stuff
Task.Run(() => {
while(true) // Do not use true but some other expression that is telling you if your application is running.
{
Thread.Sleep(60000);
lock(_updateLock)
{
foreach(APILog.Item item in _buffer)
{
//Import into database here
}
}
}
});
}
public static void Log(APILog.Item item)
{
lock(_updateLock)
{
if(_buffer == null)
_buffer = new List<APILog.Item>();
_buffer.Add(item);
}
}
}
public partial class APILog
{
public class Item
{
public string Item1 { get; set; }
public DateTime Date { get; set; }
}
}
Also in this second example I would not call APILog.Log() each time but use Middleware in combination with Attribute

Correct conversion from synchronous to async controller methods (when using void)

Using Entity Framework Core 2.0 and .NET Core 2.0 Web API controllers I am trying to rewrite them from synchronous to asynchronous methods.
This actually works easy for my controller methods just querying data.
Unfortunatly I wrapped the DbContext method SaveChanges into some helper methods for centralized logging of DB changes.
And here I start struggling how to correctly use combinations of void in an asynchronous context.
Explanation of the code:
MyController is a web api controller. The PostMethod is a (currently) synchronous post method receiving the request model, handling it, making changes and then saving the changes.
The SaveChangesWithLogs within the controller calls the extension method and prints the returned logs.
The extension method SaveChangesWithLogs generates the log entries (some before saving, some after saving), does the actual saving and returns the logs.
public class MyController : BaseController
{
[HttpPost]
public IActionResult PostMethod([FromBody]PostRequestModel request)
{
//do something
SaveChangesWithLogs();
//return created at
}
protected void SaveChangesWithLogs()
{
List logs = DbContext.SaveChangesWithLogs();
foreach (string log in logs)
{
LogInfo(log); //just prints the generated logs
}
}
}
public static class MyExtensionMethod
{
public static List SaveChangesWithLogs(this DbContext dbContext)
{
List logs = null;
//pre-save prepare logs
dbContext.SaveChanges();
//post-save modifications of logs
return logs;
}
}
In tutorials about async programming they mention the methods should be async all the way down.
So my question: How would the (method signatures) of the SaveChangesWithLogs methods look like?
public class MyController2 : BaseController
{
[HttpPost]
public async Task PostMethod([FromBody]PostRequestModel request)
{
//do something
await SaveChangesWithLogs();
//return created at
}
//does a correct implementation need async here too?
protected void SaveChangesWithLogs()
{
List logs = await DbContext.SaveChangesWithLogs();
foreach (string log in logs)
{
LogInfo(log); //just prints the generated logs
}
//return what???
}
}
public static class MyExtensionMethod2
{
public static async Task> SaveChangesWithLogs(this DbContext dbContext)
{
List logs = null;
//pre-save prepare logs
await dbContext.SaveChanges();
//post-save modifications of logs
return logs;
}
}
You just use the return type as before and wrap Task around it. There is no more magic than that involved.
I'm guessing that your List type is of some type and added that for display purposes.
protected async Task<bool> SaveChangesWithLogs()
{
List logs = await DbContext.SaveChangesWithLogs();
foreach (string log in logs)
{
LogInfo(log); //just prints the generated logs
}
return true;
}
public static async Task<List<myLogType>> SaveChangesWithLogs(this DbContext dbContext)
{
List<myLogType> logs = null;
//pre-save prepare logs
await dbContext.SaveChanges();
//post-save modifications of logs
return logs;
}

ASP.NET MVC async await deadlock need ConfigureAwait(false)?

Will this cause a deadlock? I have read where adding .ConfigureAwait(false) is needed if the calling class uses ".Result", but does that apply here with controllers... any help is appreciated. I have a bunch of this type of "stuff" going on and deadlocks seem to be happening. The server actually shows 4 threads in a w3wp dump and a lot of requests "waiting", which causes a freeze where no connections can be made, then it unhangs and resumes. rinse and repeat. I cant figure it out.
This is an MVC controller:
public class DashboardController
{
private readonly IVendorResource _vendorResource;
public DashboardController(IVendorResource vendorResource)
{
_vendorResource = vendorResource;
}
// GET: Dashboard
public async Task<ActionResult> Index()
{
var vendor = await _vendorResource.Get(1);
vendor.ToDashboardViewModel();
vendor.Emails = await _vendorResource.GetVendorEmails(1);
var model = vendor.ToDashboardViewModel();
model.PageTitle = "Dashboard";
var vendorMetrics = await _vendorResource.GetVendorMetrics(1);
model.VendorMetrics = vendorMetrics.ToVewModel();
return View("~/Views/Dashboard/Index.cshtml", model);
}
}

Benchmarking ASP.net Web API Actions

I am working on a ASP.net Web API 2 project and would like to benchmark the time of each controller action. My idea was to use ActionFilterAttribute and add a http header on the response containing the time taken.
Controller:
[Timing]
public class MyController : ApiController
{
[Route("get")]
public IHttpActionResult Get() {
System.Threading.Thread.Sleep(1000);
return Ok();
}
}
ActionFilterAttribute:
public class TimingAttribute : ActionFilterAttribute
{
private System.Diagnostics.Stopwatch timer;
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
timer = System.Diagnostics.Stopwatch.StartNew();
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
timer.Stop();
if (actionExecutedContext.Response != null && actionExecutedContext.Response.Content !=null)
{
actionExecutedContext.Response.Content.Headers.TryAddWithoutValidation("Execution-time", timer.ElapsedMilliseconds.ToString());
}
}
}
When I run this, I get execution times of less than 1 second even though I have a 1s delay in the controller. Does anyone know why this is the case or if there is a better way to benchmark Web API 2?
There are lots of things that are executed along the pipeline before OnActionExecuting is hit. Also, there are other things that are executed after OnActionExecuted, the most obvious being the HttpActionResult. Therefore It would be better to use HttpApplication.BeginRequest event to start mesasuring time, and HttpApplication.EndRequest to end measuring time.
However, I think there are better ways to benchmark a web application than log elapsed times at the server side. Fiddler has lots of nice features related to benchmarking:
You can capture the http traffic of interest by using filters.
The statistics view, where you can see lots of statistics of the selected sessions.
The time line view which shows you a nice chart about time taken by selected sessions.
You can save the sessions into a sessions archive, this is a zip file containing all information about the sessions, including xml files with timing information, that you can analize later to build you own reports.
I ran into the same problem, and found that the solution on this blog worked:
public class StopwatchAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
{
base.OnActionExecuting(actionContext);
actionContext.Request.Properties[actionContext.ActionDescriptor.ActionName] = Stopwatch.StartNew();
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
base.OnActionExecuted(actionExecutedContext);
Stopwatch stopwatch = (Stopwatch)actionExecutedContext.Request.Properties[actionExecutedContext.ActionContext.ActionDescriptor.ActionName];
if (actionExecutedContext.Response != null && actionExecutedContext.Response.Content != null)
{
actionExecutedContext.Response.Content.Headers.TryAddWithoutValidation("Execution-Time", stopwatch.ElapsedMilliseconds.ToString());
}
}
}

ActionNameAsync-ActionNameCompleted vs async-await in Asp.NET MVC

I'm starting with Async MVC and I would like to know which is the main difference between this two implementations of an AsyncController.
The first one is using the ViewNameAsync and ViewNameCompleted implementation:
public class HomeController : AsyncController
{
// ... Manager declaration ...
public void IndexAsync()
{
AsyncManager.OutstandingOperations.Increment();
Manager.ExpensiveOperationCompleted += () =>
{
Debug.WriteLine("Expensive operation completed.");
AsyncManager.OutstandingOperations.Decrement();
};
Manager.ExpensiveOperationAsync();
}
public ActionResult IndexCompleted()
{
return View();
}
}
And the second one is using async-await implementation:
public class HomeController : Controller
{
// ... Manager declaration ...
public async Task<ActionResult> Index()
{
await Manager.ExpensiveOperation();
return View();
}
}
The "main difference" is that the Async/Completed approach is using an outdated and less maintainable way to do asynchronous request handling.
The main reason you do it this way (await the same line) is to tell the thread resource manager that it can balance the thread with other threads. This will allow other threads with higher priority to finish. You can also reference your expensive operation as a variable and then later down the code block, await it there. This will allow your expensive operation to do it's thing while the rest of the code executes. Basically like using Thread.Join.
Using a completed event isn't going to work in this case, considering your IndexAsync will return before your expensive operation completes and may cause undesired results if a recycle happens.

Categories