Is Task.Run Considered Bad Practice in an Asp .Net MVC Web Application

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

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.

Is this considered bad practise in .Net Core MVC, when repeating code to do the same thing in dbcontext?

It's not bad practice - it's a matter of database design. It all depends on your needs, and why you came up with the namig that you did.
It could get hard to maintain though when the data set grows or if you have to rename fields.
One approach you can consider is using the name of the class properties in the sql query (which also implies renaming the fields in the db to match that). This would ensure that your code and your sql fields are in sync. The disadvantage is that renaming a propery in a class could break your application if you don't rename the db field too - so you have to be mindful about it.

you could rewrite your queries as:

 string query = $"SELECT "{nameof(CompanyId)}", "{nameof(CompanyName)}" FROM `ddb_companies` WHERE "{nameof(CompanyId)}" = @Val1;";

Is Task.Run or Task.Factory.StartNew are bad practice for windows phone or any other client platform?

Stephen toub's article says that exposing asynchronous wrappers for synchronous methods in a library is bad. That adds no value. If the developer wants, he can always call Task.Run(()=> SomeSynchronousMethod());. There is no need to expose it in a library. If it is an application, yes you can, because that is the only way you can off load the work.

Same applies to "Newtonsoft.Json". because it is a library.

Is Task.Run or Task.Factory.StartNew a bad practice for windows phone
or any other client platform?

Yes and no.

If you have some heavy computation to do. Say image processing or something like that. You'll anyway have to do it; It needs some cpu cycles. No matter what thread you run, it will need some amount of cpu time. Which means that you must have to consume the cpu and of course battery.

Is Task.Run or StartNew bad?

Not really when you have CPU bound work. That's what they are for.

If you need to get your work done, you need a Thread, it can't be UI thread(we need it to be responsive). So, nothing wrong in borrowing a ThreadPool thread using Task.Run or StartNew .

When it is bad?

It is bad if you're using it when you can use naturally asynchronous API. Network I/O, File I/O etc are inherently asynchronous. You don't need a thread to invoke truly asynchronous operation.

Using threads for IO is just wasting a thread by sitting and doing nothing till the underlying device to completes the IO.

In short use Task.Run for CPU bound and naturally asynchronous API for IO bound operations.

Is there any reason to run async code inside a Task.Run?

The fact that a method returns a Taskdoesn't mean it yields back immediately. It might have have some time/CPU consuming setup before an I/O operation, for example.

For that reason, it is usual to see, on client UIs, everything outside of the UI being called inside Task.Run.

That being said, this is not such a case:

public async Task SaveStuff()
{
await Task.Run(() => SaveStuffAsync().ConfigureAwait(false));
await Task.Run(() => SendToExternalApiAsync().ConfigureAwait(false));
}

That causes one extra execution in the UI thread only to schedule work on the thread pool.

this would be more acceptable:

public async Task SaveStuff()
{
await Task.Run(
async () =>
{
await SaveStuffAsync();
await SendToExternalApiAsync();
});
}

There's no need to invoke ConfigureAwait(false) because it's guaranteed to not have a SynchronizationContext.

The difference between this and your last snippet is where and how that code is being invoked,

Is it considered bad practice to reference the Microsoft.AspNet.Identity in the service layer of a multi layered web application?

  1. Is it okay to set the Thread.CurrentPrincipal in the PostAuthenticationRequest method?

Yes it is ok to assign Principal object (HttpContext.Current.User) to current thread.


  1. Is it okay to reference the using Microsoft.AspNet.Identity in my service layer?

It is not a good practice, although you can access it.

The reasons are -

  1. Service Layer should not be tightly couple with Presentation Layer.
  2. It is hard to unit-test the Service Layer.

Instead, you want to pass UserId as a parameter if you want UserId in service layer.

In Your Scenario

You want to return FinancialAccount instead of string value, and let presentation layer creates the text using string.Format().

The reason is you want to maintain Single Responsibility Principle. In other words, if you want to change the text later which happens very often, you do want to touch the Service Layer again.

public FinancialAccount GetFinancialAccountDetails(int accountId)
{
return _financialAccountRepository.GetById(accountId);
}

Very simple question about awaiting a task async

Is there a difference between these two or does the compiler do this for me?

Yes, there is. First one will block current thread until Task.Run is finished, second one will allow current thread be reused if your call is asynchronous. So it can lead to noticeable performance degradation in some cases for the first one compared to the second.

Do I actually need to do Task.Run every time I await?

No, you don't, and I would say you should (almost) never do something like this in modern codebase.

I see some people say to always use ConfigureAwait(false) and some say not to

It is a general rule of thumb when you are writing some library which can be used by anyone (UI app, or legacy ASP.NET app, or anywhere else there may be a context) . But in you case if you have "vanilla" ASP.Net Core 3.1 webapp you don't need (see the already linked post).

Also if you want to go deeper about ConfigureAwaitsee this post by Stephen Cleary and this one by Stephen Toub.



Related Topics



Leave a reply



Submit