Should I use asynchronous methods in controllers of ASP.NET Web API - c#

I was reading a book where I found that the put verb uses a same URI when we create or replace a resource while a post creates a new resource's identifier.
So in fact,
Does it mean that a post action in a controller (apicontroller) would always create a new instance of the resource?
Does it would create a new independent thread?
I don't need to worry to declare my method in my controller as async because it will create a new thread for any http request?
For a put action do I need to declare my method as async in order to avoid locks when using a web resource?

1) Does it mean that a post action in a controller (apicontroller) would always create a new instance of the resource?
2) Does it would create a new independent thread?
Yes. But remember The action verb on a method has nothing to do with the handling of the threads. in any call to API a new thread will be created or request will use an existing thread from the thread-pool.
3) I don't need to worry to declare my method in my controller as async because it will create a new thread for any http request?
The short answer is you should always write asynchronous methods if you care about scaling. read the long story for more detail.
4) For a PUT action do I need to declare my method as async in order to avoid locks when using a web resource?
As I said before it doesn't matter what is your action, PUT or POST. It's a good idea to use async methods specially if your making a blocking I/O operation, like accessing database.
Long story
Web services based on ASP.NET Web API, which exclusively supports REST, use the .NET Thread Pool to respond to requests. But just because services are inherently multithreaded does not make them scale when numerous requests are made simultaneously. The very reason why threads are pooled, instead of created on the fly, is because they are an extremely expensive resource, both in terms of memory and CPU utilization. For example, each thread consumes about 1 MB of stack space, in addition to the register set context and thread properties.
So once a thread has finished its work, it stays alive for about a minute, in the off-chance another request will arrive and the waiting thread can be used to service it. This means that if during the time a service request is being executed, another request arrives, an additional thread will be retrieved from the Thread Pool to service the second request. If there are no available threads, one will be created from scratch, which can take up to 500 milliseconds, during which time the request will block. If you have numerous requests for operations that take a long time to complete, more and more threads will be created, consuming additional memory and negatively affecting your service’s performance.
The moral of the story is: do not block the executing thread from within a service operation.
Yet, this is precisely what happens when you perform an IO-bound task, such as when you retrieve or save data from a database, or invoke a downstream service.
If the call to the database were to take a few seconds or more, and another call comes in (even for another method) an additional thread would need to be procured from the Thread Pool.
Thanks to support for asynchronous programming in .NET 4.5 and C# 5, it is extremely easy to write asynchronous methods for an ASP.NET Web API service. Simply set the return type either to Task (if the synchronous version returns void) or to Task, replacing T with the return type of the synchronous method. Then from within the method, execute a non-blocking IO-bound async operation.
Marking the method as async allows you to await an asynchronous operation, with the compiler converting the remainder of the methods into a continuation, or callback, that executes on another thread, usually taken from the Thread Pool.
Read complete article on this Build Async Services with ASP.NET Web API and Entity Framework 6

Related

Do I always need to use async/await?

I wanted to ask you about async/await. Namely, why does it always need to be used? (all my friends say so)
Example 1.
public async Task Boo()
{
await WriteInfoIntoFile("file.txt");
some other logic...
}
I have a Boo method, inside which I write something to files and then execute some logic. Asynchrony is used here so that the stream does not stop while the information is being written to the file. Everything is logical.
Example 2.
public async Task Bar()
{
var n = await GetNAsync(nId);
_uow.NRepository.Remove(n);
await _uow.CompleteAsync();
}
But for the second example, I have a question. Why here asynchronously get the entity, if without its presence it will still be impossible to work further?
why does it always need to be used?
It shouldn't always be used. Ideally (and especially for new code), it should be used for most I/O-based operations.
Why here asynchronously get the entity, if without its presence it will still be impossible to work further?
Asynchronous code is all about freeing up the calling thread. This brings two kinds of benefits, depending on where the code is running.
If the calling thread is a UI thread inside a GUI application, then asynchrony frees up the UI thread to handle user input. In other words, the application is more responsive.
If the calling thread is a server-side thread, e.g., an ASP.NET request thread, then asynchrony frees up that thread to handle other user requests. In other words, the server is able to scale further.
Depending on the context, you might or might not get some benefit. In case you call the second function from a desktop application, it allows the UI to stay responsive while the async code is being executed.
Why here asynchronously get the entity, if without its presence it will still be impossible to work further?
You are correct in the sense that this stream of work cannot proceed, but using async versions allows freeing up the thread to do other work:
I like this paragraph from Using Asynchronous Methods in ASP.NET MVC 4 to explain the benefits:
Processing Asynchronous Requests
In a web app that sees a large number of concurrent requests at start-up or has a bursty load (where concurrency increases suddenly), making web service calls asynchronous increases the responsiveness of the app. An asynchronous request takes the same amount of time to process as a synchronous request. If a request makes a web service call that requires two seconds to complete, the request takes two seconds whether it's performed synchronously or asynchronously. However during an asynchronous call, a thread isn't blocked from responding to other requests while it waits for the first request to complete. Therefore, asynchronous requests prevent request queuing and thread pool growth when there are many concurrent requests that invoke long-running operations.
Not sure what you mean by
without its presence it will still be impossible to work further
regarding example 2. As far as I can tell this code gets an entity by id from its repository asynchronously, removes it, then completes the transaction on its Unit of Work. Do you mean why it does not simply remove the entry by id? That would certainly be an improvement, but would still leave you with an asynchronous method as CompleteAsync is obviously asynchronous?
As to your general question, I don't think there is a general concensus to always use async/await.
In your second example there with the async/await keywords you are getting the value of the n variable asynchronously. This might be necessary because the GetNAsync method is likely performing some time-consuming operation, such as querying a database or perhaps you might be calling a webservice downstream, that could block the main thread of execution. By calling the method asynchronously, the rest of the code in the Bar method can continue to run while the query is being performed in the background.
But if in the GetNAsync you are just calling another method locally that is doing some basic CPU bound task then the async is pointless in my view. Aync works well when you are sure you need to wait such as network calls or I/O bound calls that will definitely add latency to your stack.

SynchronizationContext used in asynchronous server methods

So I have an async grpc C# server that needs to do a lot of cross talk between server methods (eg, a streaming response value for a stream rpc could be generated from another rpc).
I have tried setting the SynchronizationContext to a single thread based context, but server methods still seem to be called from arbitrary threads.
How could I ensure that all server methods are called on the same thread, with async/await continuations also on the same thread?
For example, see the following RPC handler:
public override Task<ResponseProto> TestRpc(RequestProto request, ServerCallContext context)
{
// Call shared instance method - could be called from
// multiple concurrent grpc requests, or streamed responses etc
SharedInstanceMethod();
// This is different every call... making a cross-thread issue
// when calling SharedInstanceMethod();
int threadId = Thread.CurrentThread.ManagedThreadId;
}
Note that in this example, SharedInstanceMethod() is a placeholder for a lot of other functions and other asynchronous events - I'm not looking to make SharedInstance thread safe.
To get continuations to run on the same thread, you could use JoinableTaskFactory.Run(() => ...) from vs-threading, which sets a SynchronizationContext to achieve this.
A problem with this is that as soon as you hit a .ConfigureAwait(false) you will lose this context, and continuations will end up running back on the thread pool threads, so if you are calling 3rd party libraries then you cannot guarantee this behavior, and if they are following best practice, then they will likely be using .ConfigureAwait(false).
But going back to your question, I don't think this is what you want. It sounds like you don't have an asynchronous workflow that needs to be forced to run synchronously on 1 thread (which is good, cause it's not ideal). You have a method that cannot be called concurrently and needs some synchronization around it, you should use lock and add a private static object field to lock on.

How we can achieve performance by implementing async controller in asp.net MVC 6?

At what point is it advisable to use async controllers in ASP.NET MVC.
Is there any coding or performance costs involved?
MSDN recommends using it for long running processes, but I was just curious if it would it be beneficial if we used it as a complete replacement to normal controllers?
We are planning to use WCF services with our controller methods.
First, async is not synonymous with "performance". In fact, using async can actually decrease performance as there's a non-trivial amount of overhead involved in async.
What async does do is release threads back to the pool when they're in a wait-state. This means that your web server is given a higher threshold before it exhausts it's "max requests" or, in other words, runs out of free threads to handle new requests.
In a synchronous request, the thread is tied up for the entire request. If there's some period of waiting involved (network latency from an API call, etc.) it's holding on to that thread even though no work is actually being done. If you got hit with 1000 simultaneous requests (the typical out-of-the-box max requests for a web server), then each further request would be queued until one for the first 1000 threads was returned to the pool.
In an async request, as soon as the thread is waiting on something to happen (i.e. not doing work), it is given back to the pool, even though the original request it was serving has not yet completed. This allows a new request to be served. When the original task that forfeited the thread completes, a new thread is requested from the pool to continue servicing that request. This effectively gives your server a little breathing room when under load. Other than that, async does nothing, at least in the context of a request being served by a web server.
In general, using async is recommended, because even that little bit of breathing room it provides may mean the difference between your server handling load or falling down. However, you should gauge your usage of async to ensure that you're actually buying something worthwhile of the overhead it adds. For example, MVC 6 lets you do things like render partials asynchronously. If your server is equipped with an enterprise class 15,000 RPM hard drive or an SSD, though, the period of waiting the thread would experience would likely be so minuscule that the passing of the thread back and forth would actually take more time than the operation itself, run synchronously.
I would say that this topic is nicely covered on this post:
When should I use Async Controllers in ASP.NET MVC?
My opinion is that it's good to use async actions when you call async methods in it (like I/O operations), it's not especially bad when you make an async action without any async calls inside, but:
You will have a needless thread switch, not a big performance penalty, but not nice either
VS will warn you, that there is no await in your async action, which can lead to unnecessary Task.Run calls

Throwing methods into a Task to avoid blocking the asp.net thread

I'm wondering if the following code has any gotcha's that I'm not aware of when running on a webserver. Reading through the excellent series http://reedcopsey.com/series/parallelism-in-net4/ I am unable to find anything that relates specifically to my question, same with the msdn, so I thought I'd bring it here.
Example call:
public ActionResult Index() {
ViewBag.Message = "Welcome to ASP.NET MVC!";
Task.Factory.StartNew(() => {
//This is some long completing task that I don't care about
//Say logging to the database or updating certain information
System.Threading.Thread.Sleep(10000);
});
return View();
}
ASP.Net supports asynchronous pages, see Asynchronous Pages in ASP.NET, but is a complicated programming model and does not bind at all with MVC. That being said, launching asynchronous tasks from a synchronous requests handler works up to a point:
if the rate at which requests add new tasks exceeds the average rate of processing your process will crash eventually. The Tasks take up live memory and eventually they will fill up the in memory queues where they're stored and your will start getting failures to submit.
.Net Taks are inherently unreliable as they lack a persistent storage, so all tasks that are submitted async must be threaded as 'abandonware', ie. if they never complete there is no loss to the application nor to the user making the request. If the task is important, then it must be submitted through a reliable mechanism that guarantees execution in the presence of failures, like the one presented in Asynchronous procedure execution.
One important thing in this case is to ensure that the code contained inside the task is wrapped in a try/catch block or any possible exceptions thrown in this thread will propagate. You also should ensure that in this long running task you are not accessing any of the Http Context members such as Request, Response, Session, ... as they might no longer be available by the time you access them.
Use new Thread instead of Task.Factory.StartNew. Task.Factory.StartNew use thread from Threads Pool and if you will have many background tasks a Threads Pool will run out of threads and will degrade your web application. The requests will be queued and your web app eventually will die :)
You can test is your background work executed on Thread Pool using Thread.CurrentThread.IsThreadPoolThread. If you get True then Thread Pool is used.

Why Wait for Asynchronous Web Services Calls

I was going through MSDN documentation on WebServices. Here and here, both these links talk about calling a webservice and wait for the response, which is also a general trend that I have seen while asynch implementation.
I don't understand "why do we need to wait for service call to return"? And, if we are waiting why don't make an synchronous call. What is the difference between an "asynch call followed by wait" and a "synchronous call"?
To be useful, the asynchronous call needs to do its thing while you go do something else. There are two ways to do that:
Provide a callback method for the asynchronous handle, so that it can notify you when it is completed, or
Periodically check the asynchronous handle to see if its status has changed to "completed."
You wouldn't use a WaitHandle to do these two things. However, the WaitHandle class makes it possible for clients to make an asynchronous call and wait for:
a single XML Web service
(WaitHandle.WaitOne),
the first of many XML Web services
(WaitHandle.WaitAny), or
all of many XML Web services
(WaitHandle.WaitAll)
to return results.
In other words, if you use WaitOne or WaitAny on an asynchronous web service that returns several results, you can obtain a single result from your web service call, and process it while you are waiting on the remaining results.
One very practical use of asynchronous calls is stuff like this
http://i.msdn.microsoft.com/Bb760816.PB_oldStyle%28en-us,VS.85%29.png
If you want to update your UI while you're waiting for a 'server' to do something, you need to make an asynchronous call. If you make a synchronous call, your code will be stuck waiting, but if you make an asynchronous call you can update the UI or even let the user go do other stuff while you're waiting for the callback. This goes beyond UI, you may make an asynchronous call to start some non-critical task and continue on with your code and its possible you don't even register for a callback if the result is unimportant.
If you do NOTHING while waiting for the asyncronous call, then its less useful.
Using asynchronous call can free up your application to do other things while waiting for the response. Since there is a fairly large amount of time (in computer cycles) waiting for a web server to respond, that time can be used for better things such as displaying a status update or doing some other work.
For example, if you had a program that performed a complicated calculation and a step of that calculation included using some reference data from a remote web service. By calling the web service asynchronously at the start of the calculation, continuing the parts of computation that can be performed locally, and then using the result of the web service call when it is available to complete the computation you can reduce the overall time of the calculation.
Since your application code is not blocked waiting for the web service to respond, you are able to utilize that wait time to the benefit of the user.
Another reason is scaling, particularly in web sites that make calls to other web services. By using asynchronous page methods (or tasks), IIS can scale your application more effectively by deferring your pages that are waiting on asynchronous web requests to whats known as an "IO thread", freeing up the main ASP.NET worker threads to serve more web pages.
The first example you're linking to issues an async call and then immediately waits for the result. Other than forking off the job to another thread, there's little difference between this and a synchronous call as far as I can tell.
The other example, however, talks about doing multiple async calls at once. If this is the case, it makes sense to launch all calls and then wait because the calls may execute in parallel.
One of the possible uses of an asynchronous call followed by a wait is that asynchronous operations often support cancellation whereas blocking calls do not. Combined with the CancellationToken pattern in .NET 4.0 (or a similar custom pattern pre-.NET4) you can create an operation that appears to be synchronous but can be cancelled easily.

Categories

Resources