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 inDelayAsync
, 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:
- When a request hits the action, ASP.NET takes a thread from the thread pool and starts executing it.
- 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:
- When a request hits the action, ASP.NET takes a thread from the thread pool and starts executing it.
- 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. - 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
Is There a Reason Image.Fromfile Throws an Outofmemoryexception for an Invalid Image Format
Asp.Net: Invalid Postback or Callback Argument
How to Configure the Web.Config to Allow Requests of Any Length
How to Populate/Instantiate a C# Array with a Single Value
Is the Use of Dynamic Considered a Bad Practice
How to Format a Datetime in a Different Format
How to Run a C# Application at Windows Startup
Algorithm for Simplifying Decimal to Fractions
Why Can't a Duplicate Variable Name Be Declared in a Nested Local Scope
Convert Any Object to a Byte[]
An Object Reference Is Required to Access Non-Static Member
How to Get Rendered HTML (Processed by JavaScript) in Webbrowser Control
How to Calculate the Angle Between a Line and the Horizontal Axis
Pass Complex Parameters to [Theory]
Find a String Between 2 Known Values
Passing Variable Between Winforms