From my understanding when we use await and the awaited task is not yet completed then the execution returns to caller. It works fine in server side(calling the async method from server side method itself). But what happends when I call from UI to an async method.
public class TestController : ApiController
{
IList<string> lstString = new List<string>();
public async Task<IList<string>> GetMyCollectionAsync()
{
lstString.Add("First");
string secString = await GetSecondString(); // I am expecting a response back to UI from here.
lstString.Add(secString);
lstString.Add("Third");
return lstString;
}
private async Task<string> GetSecondString()
{
await Task.Delay(5000);
return "Second after await";
}
}
I tested with the above API from browser like
http://localhost:port/Test
, but I got response only after 5 sec in my UI.
Am I thinking it wrongly?
Am I thinking it wrongly?
Yes. async-await does not change the nature of the HTTP protocol, which is of type request-response. When using async-await inside an ASP.NET controller, using an async method will not yield a response to the caller, it would only yield the requests thread back to the threadpool.
But if this is true, then using async method having a single await in controller side is not useful. right? because it took the same time of synchronous call
Async shines when you need scalability. It isn't about "yield this response as fast as possible", it's about being able to handle a large amount of requests without exhausting the thread-pool. Once the thread starts executing IO work, instead of being blocked, it is returned. Thus, able to serve more requests.
Async by itself does not make anything "go faster", which is a conception I see people thinking alot. If you're not going to be hitting your web service with many concurrent requests, you're most likely not going to be seeing any benefit from using it. As #Scott points out, an async method has a slight overhead as it generates a state machine behind the scenes.
async/await allow the thread to go off servicing other requests while there is that idle 5 seconds, but ultimately everything in GetMyCollectionAsync has to complete before a response is sent to the client.
So I'd expect your code to take 5 seconds and return all 3 strings in the response.
Related
I am implementing in the controller of C# Framework 4.7.2 API a method that must be asynchronous to unblock the thread (as mentioned in this article) of a heavy process so that the service can continue to serve requests from other clients, and when that process finishes return a response.
[HttpGet]
[Route("Method")]
public async Task<HttpResponseMessage> Method()
{
HttpResponseMessage task = await Task.Run(() =>
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
// response.Content...
return response;
});
return task;
}
The reason I have decided to do the asynchronous method is to improve performance. Are there other possible solutions?
You are misinterpreting that guidance.
Your method is synchronous, and Task.Run is effectively mocking asynchronous behaviour by offloading the work to a Thread Pool thread.
In an ASP.Net context, that thread is coming from the pool that is used to serve other requests, so whilst you are unblocking the current thread and releasing it back to the pool, you are instead borrowing another thread to do the work.
This thread switching does not make any more threads available, but does introduce unnecessary overhead.
What is the solution?
Well, removing the call to Task.Run will introduce a slight performance improvement, but if your service does experience throughput issues you could persist the request to a queue to be picked up by another process, allowing your Method to return early and keep your API reponsive.
Considering your code execution is synchronous marking it async for the sake of it may not make a lot of sense.
However if it is a must to have async endpoint even for synchronous operations, you could use await Task.FromResult(resultObject); or its void variant await Task.CompletedTask. This would make your code like:
[HttpGet]
[Route("Method")]
public async Task<HttpResponseMessage> Method()
{
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
// response.Content...
return await Task.FromResult(response);
}
Also look at this link from MSFT for further details
I am using async/await in MVC, but only when I have more than one task (WaitAll).
I understand that having only one task is good to have the UI free, in case of WPF or Windows Form, but does it make sense for MVC to have only one task and await for that?
I've seen it a lot in code, in MVC, but I don't get the advantages.
HTTP requests are handled by thread pool threads.
If you block a thread, it will not be able to do other work. Because the total number of threads is limited, this can led to the starvation of the thread pool and new requests will be denied - 503.
Using async code, the thread is released back to the thread pool, becoming available to handle new requests or the continuations of async code.
Like on client UIs, on the server, async code is all about responsiveness, not performance. Requests will take longer but your server will be able to handle more requests.
It depends on what you are trying to achieve. For instance, if you have multiple calls to multiple services you can always do it in a way that only the last call makes the rest of the system "wait".
You can optimise your code in a way that X asynchronously calls to services start (almost) at the same time without having to 'await' for one another.
public async Task RunSomethings()
{
var something1 = AsyncCall1();
var something2 = AsyncCall2();
var something3 = await AsyncCall3();
}
private async Task<Something1> AsyncCall1()
{
return await Something1();
}
private async Task<Something2> AsyncCall2()
{
return await Something2();
}
private async Task<Something3> AsyncCall3()
{
return await Something3();
}
I hope it helps.
Good question. Using asynchronous methods is all about using the resources effectively as well as give a good user experience. Any time you need to call on a resource that could take time to collect, it's good to use an async call.
This will do a few things. First, while a worker thread is waiting for data, it can be put on 'hold' so to speak, and that worker thread can do something else until the data is returned, an error is returned or the call just times out.
This will give you the second advantage. The interface the user is using to call the resource will be released, temporarily, to do other things. And overall, less server resources are consumed by idle processes.
I'd recommend watching the videos on this page here: https://channel9.msdn.com/Series/Three-Essential-Tips-for-Async
It's probably the clearest explanation that can help leapfrog your learning on async.
We are troubleshooting the following performance issues on a .NET Core API endpoint:
The endpoint consistently returns in less than 500MS under minor load.
When we hit the endpoint from 3 browsers, with one request a second, it gets progressively slower (within a minute of adding a third browser making calls, response times drops to 50,000MS or worse.
Each additional browser adds threads used by the API, e.g. 40 threads base, 2nd browser hitting endpoint leads to 52 threads, third spikes to 70, and so on.
When one endpoint is loaded, the entire API returns slowly (all endpoints). This is my main reason for thinking "thread exhaustion", along with point #3.
The code currently looks like this:
public IActionResult GetPresentationByEvent(int eventid)
{
return Authorized(authDto =>
{
var eventList = _eventService.GetPresentationByEvent(eventid);
return Ok(eventList)
})
}
My theory is that return Authorized(authDto => holds a thread until it returns, leading to thread exhaustion.
public async Task<IActionResult> GetPresentationByEvent(int eventid)
{
return Authorized(async authDto =>
{
Task<List<whatever>> eventList = _eventService.GetPresentationByEvent(eventid);
return Ok(eventList)
}
}
Authorized is part of a third-party library, so I can't test this easily. Would like to know if this looks like a likely problem/solution.
Yes async await can reduce thread exhaustion. In a few words thread exhaustion arise when you generate more tasks than your ThreadPool can handle.
There are subtle specifities that you can check here : Thread starvation and queuing
The only thing that you have to keep in mind on your side is that you should never block inside a task. This implies calling asynchronous code with async await (and never using .Wait or .Result on a non finished task).
If you use some blocking code wich is not using the async await pattern you have to spawn it on a dedicated thread (not the task thread queue).
My theory is that return Authorized(authDto => holds a thread until it returns, leading to thread exhaustion.
Yes. You can easily tell whether a method is synchronous by looking at its return value. IActionResult is not an awaitable type, so this method will run synchronously.
Authorized is part of a third-party library, so I can't test this easily. Would like to know if this looks like a likely problem/solution.
Possibly. It all depends on whether Authorized can handle asynchronous delegates. If it can, then something like this would work:
public async Task<IActionResult> GetPresentationByEvent(int eventid)
{
return Authorized(async authDto =>
{
Task<List<whatever>> eventList = _eventService.GetPresentationByEventAsync(eventid);
return Ok(await eventList);
});
}
Note:
Tasks should be awaited before being passed to Ok or other helpers.
This introduces GetPresentationByEventAsync, assuming that your data-accessing code can be made asynchronous.
Since making GetPresentationByEvent asynchronous may take some work, it's worthwhile to investigate whether Authorized can take asynchronous delegates before attempting this.
Does Using Async Await Avoid Thread Exhaustion?
Yes and no. Asynchronous code (including async/await) does use fewer threads, since it avoids blocking threads. However, there is still a limit. Thread exhaustion is still possible since asynchronous code needs a free thread to complete. With asynchronous code, usually you can achieve an order of magnitude or two greater scalability before you run into scalability problems like thread exhaustion.
For more conceptual information on async ASP.NET, see this MSDN article.
I'm new to using AngularJS with MVC 5 and I've been looking at using Web API with AngularJS since it seems like a good solution for loading data into your client side models.
However I've noticed that quite a few guides use async actions that returns Task<Model> and I don't understand what benefit this gives you over using just standard Web API actions (examples: http://monox.mono-software.com/blog/post/Mono/233/Async-upload-using-angular-file-upload-directive-and-net-WebAPI-service/ and http://www.asp.net/web-api/overview/getting-started-with-aspnet-web-api/build-a-single-page-application-%28spa%29-with-aspnet-web-api-and-angularjs).
Since these calls to Web API are asynchronous anyway I don't know why we need to make these method calls asynchronous. Wouldn't it be better to use just standard Web API calls?
I don't know if stackoverflow is the right place for this but I was hoping for an explanation on why calls are done this way.
The benefit of async-await on the server is scalability and performance. When you replace synchronous (blocking) operations with asynchronous (non-blocking) ones you free up threads that were previously blocked waiting which you can use to handle other requests concurrently.
async-await enables you to do more with less resources.
Let's assume we have this synchronous method:
public void Process()
{
for (int i = 0; i < 1000; i++)
{
Math.Sqrt(i);
}
Thread.Sleep(3000); // sync I/O
}
By making it async:
public async Task ProcessAsync()
{
for (int i = 0; i < 1000; i++)
{
Math.Sqrt(i);
}
await Task.Delay(3000) // async I/O
}
We can use a single thread to process multiple requests of the same method because the thread handling the request is freed up when you await the asynchronous operation.
To give another illustrative example:
Imagine 2 requests, one of which gets caught up in waiting for database for 2 seconds and the other gets caught up in application logic for 2 seconds.
Without async, at 1 second into the requests, 2 threads are in use.
With async (implemented all the way down to the database call), at 1 second into the requests, 1 thread is in use, processing application logic. The other request is in an await state (no thread used).
Both requests will take 2 seconds, but in the async scenario the number of active threads is reduced for some of the request duration
Async await on the server side is not to enable/enhance asynchronous XMLHttpRequests (AJAX calls). It is to enable the await keyword and handling of methods that return Tasks in lower-level framework code and your server-side code, should you choose to implement any. This example comes to mind:
The underlying Web API's controller dispatcher spins up a controller in response to a request and and tells it to go execute an action. It then needs to look at the response of that and take action depending on the result (error, etc.). If it executes that dispatch synchronously, the thread is blocked by the dispatcher waiting for the action to complete, when it doesn't have to be. In an async context, that dispatcher can await the response from the controller, and the thread is freed up for other tasks to run. When the original controller's action is done, any free thread can pick up where the first thread left off and handle the rest of the dispatch.
Lets say im within an ASP.NET application, WCF or web API, part of this applications job to is contact a 3rd party over the way. Id like to do this asynchronously or rather non blocking so that the thread pool doesnt get starved. However i dont want to change all my code in the service only the bit that makes the web call.
Here is some code i have written:
public string GetSomeData()
{
Task<string> stuff = CallApiAsync();
return stuff.result; //does this block here?
}
private async Task<string> CallApiasync()
{
using (var httpClient = new HttpClient())
{
string response = await httpClient.GetStringAsync(Util.EndPoint).ConfigureAwait(false);
return response;
}
}
I thought the idea was as follows but please correct any misconceptions.
The caller of CallApi can call the method and when it hits await there is a Task created which represents some work to be done asynchronously but that will take some time. At this point the thread reaches an await returns to the thread pool to do something else ie handle a different request. Once the Task completes the await line wakes up and the code continues from there as if it was synchronous.
If this is the case why do i need to return a Task from my apimethod. The caller seems to have to call stuff.Result which implies that the task may not have finished and calling result could block ? Note i don't want to make the calling method async too as then the method that calls that would need to be async etc etc.
What is the order of event here in my code?
One other question is why did i need to set configureAwait to false? otherwise everything hangs.
Id like to do this asynchronously or rather non blocking so that the thread pool doesnt get starved. However i dont want to change all my code in the service only the bit that makes the web call.
That's not possible. In order to be truly asynchronous, you must allow async to "grow" through the code as far as it needs to. What you're trying to do is block on an asynchronous call, which won't give you any benefit (you're freeing up a thread by using async, but then you're turning around and consuming a thread by using Result).
At this point the thread reaches an await returns to the thread pool to do something else ie handle a different request.
Not quite. When an async method hits an await, it returns an incomplete Task to its caller. If the caller, in turn, awaits that task, then it returns an incomplete Task to its caller, etc. When the ASP.NET runtime receives an incomplete Task from your action/service method/whatever, then it releases the thread to the thread pool.
So, you do have to go "async all the way" to see the real benefit of async.
I have an async intro on my blog if you want a more gentle introduction, as well as an MSDN article on async best practices (one of which is: async all the way). I also have a blog post that describes the deadlock you were seeing.
The compiler handles a lot of the magic behind the async pattern for you, but syntactically, you have to tell it what you want it to do by providing a method prototype that says "ok, this is an asynchronous operation that can be awaited."
For this to happen, your method must return a Task or Task<T>.
Any Task can be awaited.
You should be VERY careful when using .Result and .Wait(), as they can block in some very unexpected circumstances, because the runtime may decide to execute your method synchronously.
You should say:
await CallApiAsync();
or, to actually take advantage of it:
Task stuff = CallApiAsync();
//More code that can happen independetly of "stuff"
await stuff;
In order to do that, your GetSomeData() function must also be marked as async, but it doesn't have to, itself, return a Task.
Finished copy of a working async version of your code:
public async string GetSomeData()
{
Task stuff = CallApiAsync();
return await stuff;
}
private async Task<string> CallApiasync()
{
using (var httpClient = new HttpClient())
{
string response = await httpClient.GetStringAsync(Util.EndPoint).ConfigureAwait(false);
return response;
}
}
Honestly, if that's all the CallApiAsync function is ever going to do, you may as well inline it, though.