When Should I Use Async Controllers in ASP.NET MVC

When should I use Async Controllers in ASP.NET MVC?

Asynchronous action methods are useful when an action must perform several independent long running operations.

A typical use for the AsyncController class is long-running Web
service calls.

Should my database calls be asynchronous ?

The IIS thread pool can often handle many more simultaneous blocking requests than a database server. If the database is the bottleneck, asynchronous calls will not speed up the database response. Without a throttling mechanism, efficiently dispatching more work to an overwhelmed database server by using asynchronous calls merely shifts more of the burden to the database. If your DB is the bottleneck, asynchronous calls won’t be the magic bullet.

You should have a look at 1 and 2 references

Derived from @PanagiotisKanavos comments:

Moreover, async doesn't mean parallel. Asynchronous execution frees a
valuable threadpool thread from blocking for an external resource, for
no complexity or performance cost. This means the same IIS machine can
handle more concurrent requests, not that it will run faster.

You should also consider that blocking calls start with a
CPU-intensive spinwait. During stress times, blocking calls will
result in escalating delays and app pool recycling. Asynchronous calls
simply avoid this

When should you use Async Controllers in ASP.NET MVC?

I was reading this article recently. It think it summarizes what AsyncController are ment for.

Why do you use async if you don't promote it to the controller?

The answer is "yes", but using Task.Wait() in an action is not a good idea because it can lead to a deadlock situation.

Consider the following from the guide, Async/Await Best Practice by Stephen Cleary:

Figure 3 A Common Deadlock Problem When Blocking on Async Code

public static class DeadlockDemo
{
private static async Task DelayAsync()
{
await Task.Delay(1000);
}
// This method causes a deadlock when called in a GUI or ASP.NET context.
public static void Test()
{
// Start the delay.
var delayTask = DelayAsync();
// Wait for the delay to complete.
delayTask.Wait();
}
}

However, if you add ConfigureAwait(false) to DelayAsync() like this:

await Task.Delay(1000).ConfigureAwait(false)

then you can avoid deadlocks, as explained in the article:

Aside from performance, ConfigureAwait has another important aspect: It can avoid deadlocks. Consider Figure 3 again; if you add “ConfigureAwait(false)” to the line of code in DelayAsync, then the deadlock is avoided. This time, when the await completes, it attempts to execute the remainder of the async method within the thread pool context. The method is able to complete, which completes its returned task, and there’s no deadlock. This technique is particularly useful if you need to gradually convert an application from synchronous to asynchronous.

Always using Async in an ASP.NET MVC Controller

No. That's not a good idea to use Async everywhere.

Regarding the missing await the compiler issues a warning when an Async method does not contain an Await operator. An Async method without an await will run synchronously, which makes the semantics incorrect.

For your specific example, the operation is simple and short running, and that's why using Async/Await does not bring any benefits, and it shouldn't be used, so you are perfectly fine using:

public ActionResult Index()
{
return View();
}

Async/Await should be used for controller methods that perform some kind of IO (e.g. Network requests, Database access etc.). If a controller method is doing CPU bound work (e.g. math. calculations), then using Async/Await can actually make performance worse, unless your measurements prove me wrong.

The old rule applies: Measure twice, cut once.

What is the advantage of using async with MVC5?

The async actions are useful only when you are performing I/O bound operations such as remote server calls. The benefit of the async call is that during the I/O operation, no ASP.NET worker thread is being used. So here's how the first example works:

  1. When a request hits the action, ASP.NET takes a thread from the thread pool and starts executing it.
  2. The IdentityManager.Authentication.CheckPasswordAndSignIn method is invoked. This is a blocking call -> during the entire call the worker thread is being jeopardized.

And here's how the second call works:

  1. When a request hits the action, ASP.NET takes a thread from the thread pool and starts executing it.
  2. The IdentityManager.Authentication.CheckPasswordAndSignInAsync is called which returns immediately. An I/O Completion Port is registered and the ASP.NET worker thread is released to the thread pool.
  3. Later when the operation completes, the I/O Completion port is signaled, another thread is drawn from the thread pool to finish returning the view.

As you can see in the second case ASP.NET worker threads are used only for a short period of time. This means that there are more threads available in the pool for serving other requests.

So to conclude, use async actions only when you have a true async API inside. If you make a blocking call inside an async action, you are killing the whole benefit of it.

When should one use asynchronous controller in asp.net mvc 2?

Only use async if the operation is IO bound. A good example would be aggregating RSS feeds from multiple servers and then displaying them in a webpage.

See:

  • http://msdn.microsoft.com/en-us/magazine/ee336138.aspx
  • http://blog.stevensanderson.com/2008/04/05/improve-scalability-in-aspnet-mvc-using-asynchronous-requests/

for a good overview of asynchronous controllers.

And for more in-depth but non-MVC specific info:
http://blogs.msdn.com/tmarq/archive/2010/04/14/performing-asynchronous-work-or-tasks-in-asp-net-applications.aspx

Should async controlles always used in MVC for data access

Async is not mandatory for web applications. It is mostly mandatory for GUIs only.

Your application will continue to work. Async programming is great at handling scale of requests. But you said you have at most 100 users. If they were 100.000, your application would have suffered a lot.

And I can tell for sure that async programming does come with challenges, because for example there are issues with transactions if you don't handle it properly.

Of course threads come with a cost too. Async exists to avoid the 500KB of overhead that is required for every thread. This means that the machine(s) running the application might need to be scaled vertically. In this sense, async saves RAM.

The choice is yours. Since you are refactoring your app anyways, you could work on improving it to the next step and get it ready for bigger scale.

Otherwise your application will still work fine for 100 users.

[Edit] a pull request is worth 1000 words. In async context, the transaction should be initialized with TransactionScopeAsyncFlowOption.Enabled to avoid the exception descripted and in order to tell the transaction engine that the thread is participating an async flow. To keep it simply simple, async flows share the same thread, so application code (and transaction management is C# code) must not rely on thread-local information and has to clean up context every time the context is switched to another async flow asking for attention.

Conclusion: your first comment is correct. Async flows dramatically reduce RAM utilizations on concurrent requests.

Should I use AsyncController at ASP.NET MVC 4?

Should I use AsyncController at ASP.NET MVC 4?

No.

Should I replace uses of AsyncController to Controller?

Yes, asynchronous actions are implemented in new way in asp.net-mvc 4, using Task Class

The ASP.NET MVC 4 Controller class in combination .NET 4.5 enables
you to write asynchronous action methods that return an object of type
Task. The .NET Framework 4 introduced an asynchronous
programming concept referred to as a Task and ASP.NET MVC 4 supports
Task. Tasks are represented by the Task type and related types in the
System.Threading.Tasks namespace. The .NET Framework 4.5 builds on
this asynchronous support with the await and async keywords that make
working with Task objects much less complex than previous asynchronous
approaches. The await keyword is syntactical shorthand for indicating
that a piece of code should asynchronously wait on some other piece of
code. The async keyword represents a hint that you can use to mark
methods as task-based asynchronous methods. The combination of await,
async, and the Task object makes it much easier for you to write
asynchronous code in .NET 4.5. The new model for asynchronous methods
is called the Task-based Asynchronous Pattern (TAP). This tutorial
assumes you have some familiarity with asynchronous programing using
await and async keywords and the Task namespace.

More reading at Using Asynchronous Methods in ASP.NET MVC 4



Related Topics



Leave a reply



Submit