Is Task.Run considered bad practice in an ASP .NET MVC Web Application?

asp.net mvc scheduled task
does task.run create a new thread
c# task.run without await
task.run vs await
asp.net scheduled task
asp.net fire and forget
webbackgrounder
asp net task run
Background

We are currently developing a web application, which relies on ASP .NET MVC 5, Angular.JS 1.4, Web API 2 and Entity Framework 6. For scalability reasons, the web application heavility relies on the async/await pattern. Our domain requires some cpu-intensive calculations, which can takes some seconds (<10s). In the past some team members used Task.Run, in order to speed up the calculations.Since starting an extra thread inside ASP .NET MVC or Web API controllers is considered a bad practise (the thread is not known by the IIS, so not considered on AppDomain Recycle => See Stephen Cleary's blog post), they used ConfigureAwait(false).

Example
public async Task CalculateAsync(double param1, double param2)
{
    // CalculateSync is synchronous and cpu-intensive (<10s)
    await Task.Run(() => this.CalculateSync(param1, param2))).ConfigureAwait(false);
}
Questions
  • Is there any performance benefit in using Task.Run in an async Web API Controller for cpu-bound operations?
  • Does ConfigureAwait(false) really avoid the creation of an extra thread?

Is there any performance benefit in using Task.Run in an async Web API Controller for cpu-bound operations?

Zero. None. In fact, you're hindering performance by spawning a new thread. Within the context of a web application, spawning a thread is not the same thing as running in the "background". This is due to the nature of a web request. When there's an incoming request, a thread is taken from the pool to service the request. Using async allows the thread to be returned before the end of the request, if and only if the thread is in a wait-state, i.e. idle. Spawning a thread to do work on, effectively idles the primary thread, allowing it to be returned to the pool, but you've still got an active thread. Returning the original thread to the pool does nothing at that point. Then, when the new thread finishes its work, you've got to request a main thread back from the pool, and finally return the response. The response cannot be returned until all work has completed, so whether you use 1 thread or a hundred, async or sync, the response cannot be returned until everything finishes. Therefore, using additional threads does nothing but add overhead.

Does ConfigureAwait(false) really avoid the creation of an extra thread?

No, or more appropriately, it's not about that. ConfigureAwait is just an optimization hint, and only determines whether the original context is maintained between thread jumps. Long and short, it has nothing to do with the creation of a thread, and at least in the context of an ASP.NET application, has negligible performance impact either way.

c#, Is there any performance benefit in using Task.Run in an async Web API Controller for cpu-bound operations? Zero. None. In fact, you're  In the past some team members used Task.Run, in order to speed up the calculations.Since starting an extra thread inside ASP .NET MVC or Web API controllers is considered a bad practise (the thread is not known by the IIS, so not considered on AppDomain Recycle => See Stephen Cleary's blog post ), they used ConfigureAwait(false).


Is there any performance benefit in using Task.Run in an async Web API Controller for cpu-bound operations?

No. And it doesn't matter whether it's CPU bound or not.

Task.Run offloads work to a ThreadPool thread. The web api request already uses a ThreadPool thread so you're just limiting scalability by offloading to another thread with no reason.

This is useful in UI apps, where the UI thread is a special single thread.

Does ConfigureAwait(false) really avoid the creation of an extra thread?

It doesn't affect thread creating in one way or another. All it does is configures whether to resume on the captured SynchronizationContext or not.

Task.Run Etiquette Examples: Don't Use Task.Run in the , Warning: bad code! class MyService { public Task<int> NET MVC controller that returns a view using the (original, synchronous) service. The UI app has its nice asynchronous method, and the ASP. Consider all the examples where synchronous and asynchronous APIs exist side-by-side, e.g., Entity  Thanks for the info and the link to the helpful blog post. From what I understand, it sounds like in this trivial case Task.Run(Function() RunAsync()) is the best option since it's just passing through, and uncaught exceptions will still be captured in an AggregateException when awaiting Task.Run.


Is there any performance benefit in using Task.Run in an async Web API Controller for cpu-bound operations?

Think about what really happens - Task.Run() creates a Task on the thread pool, and your await operator will free the thread (I'm assuming all methods down the stack are also awaiting). Now your thread is back to the pool, and it might pick up that same Task! In this scenario, there is obviously no performance gain. There is performance hit, actually. But if the thread picks up another Task (that's probably what will happen), another thread would have to pick up CalculateSync() Task and continue from where the former stopped. It would have made more sense to let the original thread execute CalculateSync() in the first place, no Tasks involved, and let the other thread have the other queued Tasks.

Does ConfigureAwait(false) really avoid the creation of an extra thread?

Not at all. It merely points out that the continuation shouldn't be executed on the caller's context.

How to run Background Tasks in ASP.NET, Scott Hanselman on Programming, The Web, Open Source, .NET, The NET application just needs one background task to runs an a basic scheduled interval​, than perhaps you just need the basics of Here's an example that kicks of a background work item from an MVC action: too bad Hangfire is . maybe you wanna use a scheduled task. Doing this in a MVC is a bad idea (mixing responsabilities) and building a windows service looks like an overkill to me (because is something doesn't need to run all the time).


There is one more thing that you need to consider. As you told your your api is doing CPU intensive task then async/await help to run the process in another thread and free your app pool for another request. Means your web api can handle more number of request per second if you use async/await correctly.

In your case look like this.CalculateSync(param1, param2) is non-async method so to call this asynchronously you have to use Task.Run.

I'll recommend to remove .ConfigureAwait(false) as this will actually decrease your performance.

ASP.NET Core Performance Best Practices, Rather than waiting on a long-running synchronous task to complete, the thread can work on another request. Run and immediately await it. ASP.NET Core already runs app code on Do consider caching frequently accessed data retrieved from a This is a bad practice because the work item could:. Best Practices to Improve ASP.Net Web Application Performance. [B]Introduction[/B] Performance tuning can be tricky. It's especially tough in Internet-related projects with lots of components running around, like HTML


ConfigureAwait FAQ, NET added async / await to the languages and libraries over seven years that queues Task s to run on whatever SynchronizationContext. Consider a library method that uses await on the result of some NET MVC controller, whether or not the app model did in fact publish a bad behavior will result. .NET 4.5.2 introduces HostingEnvironment.QueueBackgroundWorkItem to help run background tasks in an asp.net app domain. The method registers the task with asp.net so that the runtime will know about it during recycles or app shutdowns, and it gives you a CancellationToken that will cancel whenever an event like this is triggered.


Advanced Tips for Using Task.Run With Async/Await, Run apply to a web application framework such as ASP.NET Core? There are certainly a number of advantages to using async/await with ASP. In the past some team members used Task.Run, in order to speed up the calculations.Since starting an extra thread inside ASP .NET MVC or Web API controllers is considered a bad practise (the thread is not known by the IIS, so not considered on AppDomain Recycle => See Stephen Cleary's blog post), they used ConfigureAwait(false).


C# 8 and .NET Core 3 Projects Using Azure: Build professional , Build professional desktop, mobile, and web applications that meet modern inside a constructor like this is generally considered bad practice, as it makes it [92 ] Task Bug Logging ASP.NET Core MVC App Using Cosmos DB Chapter 2. So, in this demonstration, you will learn about the best practices which should be implemented when creating MVC application. Isolate Components ASP.NET MVC application contains several components, like Model, Controller, View, Data Access Logic, Repository Logic, Service Layer etc.