I have one HTTP post call in angularjs which takes around 7-8 secs to complete the task. The url is action method of one controller in MVC. As it is taking a lot of time I don't want my user to wait for this operation but can navigate to any other page or even can continue with different operations on the same page. once the operation gets complete, it will notify user for either the success or failure.Currently any other http post waits for this post to get complete before showing it's respective result. I need help in what can be done for this scenario. What is the best approach? I checked this below link and I see some suggestions. Will it be helpful? link- http://tech.pro/tutorial/1252/asynchronous-controllers-in-asp-net-mvc
AngularJS Code-
$http({
url: key_Url_Generate,
method: Post,
params: $scope.PlanDetails
}).then(function (result) {
//Notify user for success or failure
}
Controller Action Method-
[HttpPost]
public ActionResult GenerateLtdQuote(LTD_PlanDetailsVM ltdPlanDetailsVM)
{
// time consuming operation here
}
No, async, at least in terms of C#, merely allows the thread to be returned to the pool while it is in a wait state, i.e. waiting for something like an external service to respond. It does not make the action return quicker. In fact, if anything async can make things slower, as it adds overhead. If the endpoint being hit by your AJAX does anything that puts the thread in a wait state, where it's doing nothing but waiting for some external process to complete, then you should use async on it, but only because it allows the server to more efficiently use resources. It won't make anything happen any quicker, though.
Async, in terms of JavaScript, is a little different, as JavaScript process will continue. That is why you have a callback for AJAX requests. When whatever resource is being accessed remotely finally responds, the callback will be invoked, but other things can still happen in the meantime. This actually makes your question more confusing, though, because by using AJAX, your page should not be blocked at all and the user should still be able to interact with the page and do whatever they want. The only way this wouldn't occur is if you're running AJAX synchronously, which is actually a little hard to do by accident, and should definitely be avoided.
Related
This question already has answers here:
When should I use Async Controllers in ASP.NET MVC?
(8 answers)
Closed 6 years ago.
I am working with a pre-existing C# ASP.NET MVC webapplication and I'm adding some functionality to it that I can't decide whether or not to make async.
Right now, the application home page just processes a page and a user logs in. Nothing more, and nothing asynchronous going on at all.
I am adding functionality that will, when the homepage is visited, generate a call to a Web API that subsequently calls a database that grabs an identifier and returns it to an HTML tag on the home page. This identifier will not be visible on the screen, only on the source/HTML view (this is being added for various internal tracking purposes).
The Web API/database call is simple, just grab an identifier and return it to the controller. Regardless, I'm wondering whether the app should make this call asynchronously? The website traffic isn't immense, but I'm still wondering about concurrency, performance and future scalability.
The one catch is that I'd have to make the entire ActionMethod async and I'm not sure what the affects of that would be. The basic pattern, currently synchronous, is below:
public ActionResult Index()
{
var result = GetID();
ViewBag.result = result.Data;
return View();
}
public JsonResult GetID()
{
var result = "";
var url = "http://APIURL/GetID";
using (WebClient client = new WebClient())
{
result = client.DownloadString(url);
}
return Json(result, JsonRequestBehavior.AllowGet);
}
Any thoughts?
First and foremost, realize the purpose of async, in the context of a web application. A web server has what's called a thread pool. Generally speaking, 1 thread == 1 request, so if you have a 1000 threads in the pool (typical), your website can roughly serve 1000 simultaneous requests. Also keep in mind that, it often takes many requests to render a single resource. The HTML document itself is one request, but each image, JS file, CSS file, etc. is also a request. Then, there's any AJAX requests the page may issue. In other words, it's not uncommon for a request for a single resource to generate 20+ requests to the web server.
Given that, when your server hits its max requests (all threads are being utilized), any further requests are queued and processed in order as threads are made available. What async does is buy you some additional head room. If there's threads that are in a wait-state (waiting for the results of a database query, the response from a web service, a file to be read from the filesystem, etc.), then async allows these threads to be returned to the pool, where they are then able to field some of those waiting requests. When whatever the thread was waiting on completes, a new thread is requested to finish servicing the request.
What is important to note here is that a new thread is requested to finish servicing the request. Once the thread has been released to the pool, you have to wait for a thread again, just like a brand new request. This means running async can sometimes take longer than running sync, depending on the availability of threads in the pool. Also, async caries with it a non-insignificant amount of overhead that also adds to the overall load time.
Async != faster. It can many times be slower, but it allows your web server to more efficiently utilize resources, which could mean the difference between falling down and gracefully bearing load. Because of this, there's no one universal answer to a question like "Should I just make everything async?" Async is a trade-off between raw performance and efficiency. In some situations it may not make sense to use async at all, while in others you might want to use it for everything that's applicable. What you need to do is first identity the stress points of your application. For example, if your database instance resides on the same server as your web server (not a good idea, BTW), using async on your database queries would be fairly pointless. The chief culprit of waiting is network latency, whereas filesystem access is typically relatively quick. On the other hand, if your database server is in a remote datacenter and has to not only travel the pipes between there and your web server but also do things like traverse firewalls, well, then your network latency is much more significant, and async is probably a very good idea.
Long and short, you need to evaluate your setup, your environment and the needs of your application. Then, and only then, can you make smart decisions about this. That said, even given the overhead of async, if there's network latency involved at all, it's a pretty safe bet async should be used. It's perfectly acceptable to err on the site of caution and just use async everywhere it's applicable, and many do just that. If you're looking to optimize for performance though (perhaps you're starting the next Facebook?), then you'd want to be much more judicious.
Here, the reason to use async IO is to not have many threads running at the same time. Threads consume OS resources and memory. The thread pool also cal be a little slow to adjust to sudden load. If your thread count in a web app is below 100 and load is not extremely spikey you have nothing to worry about.
Generally, the slower a web service and the more often it is called the more beneficial async IO can be. You will need on average (latency * frequency) threads running. So 100ms call time and 10 calls per second is about 1 thread on average.
Run the numbers and see if you need to change anything or not.
Any thoughts?
Yes, lot's of thoughts...but that alone doesn't count as an answer. ;)
There is no real good answer here since there isn't much context provided. But let's address what we know.
Since we are a web application, each request/response cycle has a direct impact on performance and can be a bottleneck.
Since we are internally invoking another API call from ours, we shouldn't assume that it is hosted on the same server - as such this should be treated just like all I/O bound operations.
With the two known factors above, we should make our calls async. Consider the following:
public async Task<ActionResult> Index()
{
var result = await GetIdAsync();
ViewBag.result = result.Data;
return View();
}
public async Task<JsonResult> GetIdAsync()
{
var result = "";
var url = "http://APIURL/GetID";
using (WebClient client = new WebClient())
{
// Note the API change here?
result = await client.DownloadStringAsync(url);
}
return Json(result, JsonRequestBehavior.AllowGet);
}
Now, we are correctly using async and await keywords with our Task<T> returning operations. This will help to ensure ideal performance. Notice the API change on the client.DownloadStringAsync too, this is very important.
I'm writing a small internal web app.
I need to do a very long operation (which can take about an hour) at the press of a button and let the user know once the operation completes with its result.
In other words, I need the button to start the async operation and refresh the view with the results once it is finished (after about an hour run).
Edit: The operation could use some sort of a refresh mechanism in the View. The result can be sent to the view after a small lag (doesn't have to refresh realtime)
You could use SignalR, but that might be a little bit overkill for this. Another option is to set up another controller action which checks if the task has been completed. Then, on the client side, you could use jQuery to make ajax requests to that controller action. When the action comes back as complete you can show an alert or otherwise update the page.
$.ajax({
type: 'GET',
url: http://mysite.info/tasks/checkComplete/5,
success: function (response) {
if (response == 'true') {
alert('Task complete');
}
}
});
As for what happens on the server side, I don't think this is a case where I would use async/await. If your task is really going to be running for an hour I have a feeling you're going to run into timeout issues, etc. I would have a controller action which is used to start the task, but all it does it put the request to start in the database. I would then have an external "worker" which checks for requests in that database and performs the tasks. Once the task is complete it would update that database entry to mark it as complete. Then the "CheckComplete" controller action from my example above could check the database to see if the task is in fact completed.
As suggested in the comments, I recommend you to take a look at SignalR, it's not that hard to implement.
You'll have to implement a server on your website, send a message to the server when your long operation is complete, and refresh your view when the message is received.
The tutorials from Microsoft should be clear enough for that.
A low tech solution from the age way before AJAX and WebSockets was to simply continually write data to the response (usually a progress report).
So instead of doing the work asynchronously, you would call something like
Response.Write("<script>reportProgress(" + progress + ");</script>");
Response.Flush();
once in a while. It has its issues, but it might still be a good way if you have to support weird platforms or very old browsers.
Ummm,
I will try to create flag into the server when finished the work.
In the MVC you can will create a TIMER obj that check, for example each minute, if the server has finished the work, and launch this timer in a new thread that not block the app.
(sorry, for my english).
I'm still not quite clear about async and await in .net 4.5. So far, I think I understand that await:
puts the function (to its right) on a separate thread.
puts the execution back to the current function's caller
but holds the rest of the current function's code "hostage" until the awaiting (async) function is finished.
Please correct me if I'm misunderstanding something. So, if the above is true, I'm stuck with an ApiController's Post function that I want async:
[HttpPost]
public async Task<HttpResponseMessage> Post([FromBody]MyObject obj)
{
myDataContext.MyObjects.InsertOnSubmit(obj);
myDataContext.SubmitChanges();
await SomeReallyLongRunningTaskAsync();
// obj would now have the new Id, which I'm really after.
return Request.CreateResponse(HttpStatusCode.Created, obj);
}
So if I'm understanding this correctly, Post will finish execution and return control to whoever called myApiController.Post(obj). But I don't have the HttpResponseMessage object yet since await held return Request.CreateResponse(HttpStatusCode.Created, obj); "hostage".
In this above simple example, would the call immediately return to the client (that is, client JS website or mobile app)? If so, would it be a 201, 400, 500 (better not), others?
In addition to Stephen's answer I need to point out a few things.
First, async in the controller does not make the user experience async. User will have to wait as long as SomeReallyLongRunningTaskAsync() takes. [So why do we do async? See the next point]
Also, if the SomeReallyLongRunningTaskAsync() is CPU-bound, then you should not call it in async mode. The main reason to use Async in a server scenario is to release the CLR thread back to the pool so that the IO Completion Port (IOCP) can handle the rest - until IO work done which then goes back to the thread pool. This will prevent the problem of Thread Starvation which is common in ASP.NET Scenarios.
IOCPs are used ONLY in IO-bound situations, examples are:
reading from/writing to a file
accessing database or
accessing an external Web Service or WCF service
There are tons of resources available online and explain various aspects. If I may put a plug, Chapter 2 of this book is an excellent resource which gives a cohesive understanding of Async in Web API.
puts the function (to its right) on a separate thread.
No. async does not start a new thread. I have an async intro that you may find helpful.
Post will finish execution and return control to whoever called myApiController.Post(obj). But I don't have the HttpResponseMessage object yet
Correct.
In this above simple example, would the call immediately return to the client (that is, client JS website or mobile app)?
No. ASP.NET MVC 4.5 sees that you're returning Task<HttpResponseMessage> and not HttpResponseMessage, so it will not send the response until your Task is completed (at the end of your async Post method).
I'm starting to learn MVC.net and following this documentation.
In there, it is explained that an async controller will implement two methods, say the action is called News, then we will have a method called NewsAsync, which will return void, and a NewsCompleted, which will return a view, and that will be invoked once the outstanding operation returns.
My concern is that, i really don't see any point to an asynchronous operation that cannot return a view after the operation started. If the user will be unable to see any feedback whatsoever from the service until the asynchronous callback returns, then why bother with an asynchronous controller in the first place?
Is there any way to return an intermediate view after the async operation starts? Am i needlessly concerned about this apparent limitation? is there something i'm missing from the MVC.net?
The point of the asynchronous controller is to promote thread re-use so that if you have a particularly long running request that blocks on resources, you aren't going to be tying up the request queue. It has nothing to do with returning back information to the requesting party. To their end, they see no difference between an async controller and a normal controller.
It's not like it makes it more ajax friendly or whatever; a good example would be if you had a request start to render an image; traditionally, that request thread is going to be consumed while the CPU renders the image. With the asynchronous pattern, you can still be rendering the image, but that thread could be freed to service another web request until the render is complete, allowing greater throughput for your server.
One strategy is to set up polling on the client. Once the result has been generated the user will be notified.
When i saw the first news about await, i was very excited and i thought many ways of using it.
One of these is to use it in my web framework to hide the asynchronous aspect of client/server exchanges like it's done in several frameworks.
So here is the deal:
I would like to write things like that:
{
Page p = new Page();
FormResponse response = await p.Show();
var field1 = reponse.inputField["input1"];
...
}
I would like the dev to be able to write this code on the server. As you guess p.Show() write in the HttpResponse the html code displaying the page with the form, and send the response to the client, so, the thread is
killed and i never reach the next instruction (FormResponse response =).
So here is my question:
Is there any way of doing such a thing ? I know await cut the code, pack it in a continuation, make the closure for us, and store it somewhere to call it back when p.Show() is done.
But here, the thread is going to be killed, and this is my code which recieve the submit response from Page which has to deal with it. So i have to restore the continuation that "await" created and execute it myself.
Am i getting high or is it possible ?
Edit : additional infos
I can explain a bit more, but we need an example.
Imagine you want to make an async call to a webservice, you just use await and then call the webs.
A webs doesn't display any page, it returns pieces of information and you can continue the next instructions, so with a webs we have : Client -> Server A [-callwebs-> Server B ->] Server A -> Client.
Now, imagine a webs wich has to display a user interface to grab some information from the user, we can call this kind of webs a UIwebs (a reusable interface called by several webapp),
it displays the ui, grabs the info, and sends it back to the caller.
So with a UI webs we have : Client -> Server A [-response_redirect-> Client -get-> Server B (here is the UIwebs, the client inputs whatever) -response_redirect-> Client -get-> ] Server A -> Client
What i put between brackets has to be handle in the way by the developper :
so for a classic webs, i can imagine the asynchronous page is "sleeping" waiting the webs to response, but with a UI webs we have to response à redirect to the client, so the page is done for asp.net, and SynchronizationContext says that there is no more async instruction to wait for.
In fact, my need here is the same as turning on the web server, and sending a request to it wich coule restore everything needed to execute the code just after the await.
Regards,
Julien
I'm not sure what the problem is.
If you have, e.g., ASP.NET asynchronous pages, then any top-level (async void) function will properly notify ASP.NET that the page is incomplete and release the thread. Later, the continuation will run on a (possibly another) thread, restore the request context, and finish the request.
The async design was carefully done to enable this exact behavior. In particular, async void increments the outstanding asynchronous operation count in SynchronizationContext, as I described in a recent MSDN article.
If you're running your own host (i.e., not using ASP.NET), then you'll have to implement SynchronizationContext. It's non-trivial but not extremely hard, either. Once this is done, async and await will "just work". :)
Updated answer in response to edit:
Keep in mind that await/async are just syntactical sugar; they don't enable anything that wasn't possible before - they just make it easier.
If I understand your situation correctly, you want a web service to return a UI and then respond to it. This is an inversion of how HTTP works, so you'd have to do some funky stuff with viewstate. I'll think about it...