Make ActionResult Asynchronous To Increse Performance And elimate Flickering - asp.net-mvc

I want to make this Action Asynchronous,Can Anyone Help On this.
[HttpGet]
public ActionResult LoadAddressDetail(int? whId)
{
try
{
return Json(new
{
GridData = wareHouseMasterService.LoadAddressGrid(GetCommonProperty(), whId ?? 0, DataManager.CustomerType, DataManager.CustomerTypeCode.WAREHOUSE.ToString()),
Status = true
}, JsonRequestBehavior.AllowGet);
}
catch (Exception e) { this.loggerService.Error(e); return Json(false, JsonRequestBehavior.AllowGet); }
}
Since I am Using Three httpget Methods executed at one page load and the screen flickers Three Times.So I need parallel Processing.

Not sure exactly what you're looking for here. Making an action async is as simple as adding the async keyword and returning Task<ActionResult>:
public async Task<ActionResult> LoadAddressDetail(int? whId)
Of course, then, you must await something. The only thing I see that seems to do any work is wareHouseMasterService.LoadAddressGrid, but you've provided no details about what this does. Generally speaking, you would need to make this method async, as well, or add an async version of it. Then, you would simple do:
GridData = await wareHouseMasterService.LoadAddressGridAsync(...),
All that said, there's a big gotcha to keep in mind. Async, in the context of a web request, isn't the same thing as parallel processing, and it also does not make anything happen "faster". Additionally, there's a minor performance impact from using async, as there's overhead that goes along with that. In other words, simply making this action action async does not really in fact serve any other your mentioned goals.
The true reason to use async is to allow your web server to handle load more efficiently. When the thread handling the request is in a wait-state, async allows the thread to be returned to the pool to field other requests. Since there's a ceiling to the amount of threads a web server can spawn, and therefore the number of requests it can handle simultaneously, async gives you some extra head room when the server is under load. That's pretty much it, though.
That said, if you're trying all this out in development, using IIS Express, it's important to realize that IIS Express is single-threaded. In other words, requests are queued and handled serially, since raw performance is not a real factor in development. Therefore, in this situation, your three AJAX requests are being processed one at a time, rather than in parallel as they likely would be in full IIS, and that may be the source of what you're experiencing. Async may help here, but not necessarily. Regardless, it's only an issue in development.
Short of all that, you need to look at your JavaScript and ensure that you are doing things in an optimized way such that the AJAX requests are processed efficiently. There's also ways to minimize the flash of unstyled content issues apart from simply making everything happen quicker. However, since you've posted no code in this regard, there's not more that can be said.

Related

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

I'm trying to figure out how to use async/await in C# in my Asp.Net MVC.
The main point seems to be that it helps asp.net for releasing threads from the worker pool when you are doing IO (so they can process other stuff). For doing so you have to promote the async/await modifier from the method doing the IO call up to the controller action (you better have just a few layers).
Is there any point in using this feature without promoting the async/await up to my controller ? (by adding Task.Wait after a call to an Async method for instance).
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.
Do not use Task.Wait as it can deadlock or produce an AggregateException. If you need to do this then you should use Task.WhenAll which is non-blocking.
Generally though, it is safest to use async code end-to-end. The benefit of using async away through the entire stack is that your code will be easier to debug and error handling much simpler.
So yes, if you are going to use async/await - include it in your controller and avoid using blocking code like Task.Wait.

Using AsyncController to help increase concurrency on a legacy ASP.NET MVC 3 project

We have a website that is struggling with concurrent users right now.
Here is the very high-level background of the project:
Legacy ASP.NET MVC 3 project (.NET 4)
Can't do any major rewriting of core code
Main entry point that takes the longest time to execute is the SubmitSearch action on the Search controller. Average time to respond is 5-10 seconds.
So as the second point outlines, we don't want to spend too much time on this project rewriting large sections. However, we want to attempt to increase concurrent users. We're not looking to change anything else or increase performance since it would require much more work.
What we are seeing is that as more people hit SubmitSearch, the web site in general slows down. That's most likely due to all the IIS threads being locked up executing the search.
We are looking to implement AsyncController and making the SubmitSearch action execute on a normal CLR thread. Here's how we wanted to implement it:
Assume this is the original SubmitSearch method:
/// <summary>
/// Submits a search for execution.
/// </summary>
/// <param name="searchData">The search data</param>
/// <returns></returns>
public virtual ActionResult SubmitSearch(SearchFormModel searchData)
{
//our search code
}
The quickest way we were hoping to convert to AsyncController is to simply do this:
/// <summary>
/// Submits a search for execution.
/// </summary>
/// <param name="searchData">The search data</param>
/// <returns></returns>
protected virtual ActionResult SubmitSearch(SearchFormModel searchData)
{
//our search code
}
/// <summary>
/// Asynchronous Search entry point
/// </summary>
/// <param name="searchData"></param>
public void SubmitSearchAsync(SearchFormModel searchData)
{
AsyncManager.OutstandingOperations.Increment();
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
ActionResult result = SubmitSearch(searchData);
AsyncManager.Parameters["result"] = result;
AsyncManager.OutstandingOperations.Decrement();
});
return;
}
/// <summary>
/// Called when the asynchronous search has completed
/// </summary>
/// <param name="result"></param>
/// <returns></returns>
public ActionResult SubmitSearchCompleted(ActionResult result)
{
//Just return the action result
return result;
}
Of course this didn't work because all through-out the code, we are referencing HttpContext.Current, which we know ends up being null in this approach.
So we were then hoping to do this with SubmitSearchAsync:
/// <summary>
/// Asynchronous Search entry point
/// </summary>
/// <param name="searchData"></param>
public void SubmitSearchAsync(SearchFormModel searchData)
{
AsyncManager.OutstandingOperations.Increment();
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
ActionResult result = null;
AsyncManager.Sync(() =>
{
result = SubmitSearch(searchData);
});
AsyncManager.Parameters["result"] = result;
AsyncManager.OutstandingOperations.Decrement();
});
return;
}
This fixes the issue.
So here's my concern:
Does wrapping the execution of SubmitSearch in the AsyncManager.Sync method defeat the purpose of using this model? In other words, when we are within the AsyncManager.Sync method, are we back on the IIS threads, which puts us back at square one?
Thanks
Does wrapping the execution of SubmitSearch in the AsyncManager.Sync method defeat the purpose of using this model? In other words, when we are within the AsyncManager.Sync method, are we back on the IIS threads, which puts us back at square one?
More or less, yes. But unfortunately, in your case, using Task.Factory.StartNew also defeats the purpose of using an async controller. With the approach you're trying to use, you can't win.
IIS threads, threads started by ThreadPool.QueueUserWorkItem, and Task threads, are all taken from the same thread pool.
In order to gain any benefit from async controllers, you need true async methods. In other words, methods like Stream.ReadAsync or WebRequest.GetResponseAsync. These specially-named methods use I/O completion ports instead of normal threads, which use hardware interrupts and operate on a different thread pool.
I wrote about this a long time ago in my answer here: Using ThreadPool.QueueUserWorkItem in ASP.NET in a high traffic scenario. Tasks and awaiters are pretty sweet, but they don't change the fundamental dynamics of the .NET thread pool.
One thing to note is that there is an option, TaskCreationOptions.LongRunning, that you can specify when creating a Task, which essentially informs the framework that the task will be doing a lot of waiting, and in theory the TPL will attempt to avoid scheduling it in the thread pool. In practice, this probably won't be very practical on a high-traffic site because:
The framework doesn't actually guarantee that it won't use the thread pool. That's an implementation detail, and the option is simply a hint that you provide.
Even if it does avoid the pool, it still needs to use a thread, which is essentially like using new Thread - if not literally then at least effectively so. What this means is heavy context-switching, which absolutely kills performance and is the main reason why thread pools exist in the first place.
A "search" command clearly implies some kind of I/O, which means there's probably a real asynchronous method you can use somewhere, even if it's the old-style BeginXyz/EndXyz. There are no shortcuts here, no quick fixes; you'll have to re-architect your code to actually be asynchronous.
The .NET framework can't inspect what's going on inside your Task and magically convert it into an interrupt. It simply cannot make use of an I/O completion port unless you refer directly to the specific methods that are aware of them.
Next web or middleware application you work on, try to consider this ahead of time and avoid synchronous I/O like the plague.
I think #Aaronaught has the best answer so far: you need true asynchronous processing in order to scale (i.e., Begin/End, not just using thread pool threads), and that there are no shortcuts or quick fixes to asynchronous code - it will take a re-architecting of at least that portion.
Which brings me to this part of your question:
we don't want to spend too much time on this project rewriting large sections.
The best bang for your buck is probably to purchase more memory and stick that in the server. (You should check with a profiler first just to make sure it is a memory issue - memory usually is the limiting factor on ASP.NET but it's best to check first).
As much as we developers love to solve problems, the truth is we can burn a lot of hours, e.g., changing synchronous code to asynchronous. FYI, the Task-based Asynchronous Pattern (async/await) in .NET 4.5 will allow you to change synchronous code to asynchronous much more easily.
So for now I say buy a couple RAM chips and make a mental note to do the (much easier) upgrade to async after you change to .NET 4.5.
I would start by looking at the performance of the server itself and then consider using the profiling tools in visual studio to identify exactly what and where the bottleneck is. Consider looking at the mini profiler a discussion of which can be found here http://www.hanselman.com/blog/NuGetPackageOfTheWeek9ASPNETMiniProfilerFromStackExchangeRocksYourWorld.aspx. Generally agree with the comment above about thread consumption.
There are dozens of reasons that can cause the server to slow down. If we only talk about threads, threads consume a minimum of 1/4 memory each, that means the more threads drawn up from the thread pool, the more memory is consumed. This can be one of the problems causing the server to slow down.
If the response from server takes over 10 seconds, consider using Asynchronous. Like in your code, make SubmitSearchAsync function Asynchronously, it will avoid blocking a thread, and also releases the thread back to thread pool. However, like the code you provided, when a request is received from the SubmitSearchAsync action, a thread is drawn from the thread pool to executed its body.
The SubmitSearch is a synchronous action, it waits until the implementation is finished, and it blocks the thread until the implementation finishes.
In other word, you released one thread, but you also blocked another thread. If you need to synchronize code from an asynchronous thread, use the AsyncManager.Sync method. But in your case, AsyncManager.Sync might not help much. I suggest two possible solutions:
1) manually spawning a thread:
public virtual ActionResult SubmitSearch(SearchFormModel searchData){
new Thread(() => {
//your search code
}).Start();
}
In this case, your search code might take longer, but the execution of the search will be done on a thread not a part of the pool.
2) change the SubmitSearch function asynchronously along with using Parallelism:
protected virtual async Task<ActionResult> SubmitSearch(SearchFormModel searchData){
// Make your search code using Parallel task like below.
var task1 = DoingTask1Async(searchData);
var task2 = DoingTask2Async(searchData)
await Task.WhenAll(task1,task2);
}
Aside from above suggestion, consider using Cancellation tokens, it further reduces thread usage.
Hope it helps.
What we are seeing is that as more people hit SubmitSearch, the web site in general slows down. That's most likely due to all the IIS threads being locked up executing the search.
If it was the threads locked up then it wouldn't be a slow down but probably http errors were returned. Can I ask how many parallel hits causes the slow down? The threadpool in .Net4 is quite big. Also, if your search takes 10 seconds that means your database is doing the heavy-lifting. I would have a look at the DB performance: if other parts of your site are also DB dependent then several parallel DB intensive searches will slow down your application.
If for some reason you can't/don't want to perfmon the database then here is a simple test: change the database search call to a sleep call for X seconds (around 10 in this case). Then run your parallel requests and see if the site responsiveness drops or not. Your request thread numbers are the same so if that was the reason then it should have the same effect.

How to set ViewBag for _Layout in MVC4 using async in every action

The usecase is simple. Info for logged in user is displayed in _Layout.cshtml. That info needs to be refreshed every time.
I found two ways to do that
Have BaseController and in its OnActionExecuting method set ViewBag.UserInfo = ...; which is later used in _Layout.cshtml
In _Layout.cshtml do #{Html.RenderAction("GlobalUserInfo", "UserInfo");}
The problem is that these two ways fail miserably with deadlocks or exceptions if UserInfo is returned from an async public async Task<UserInfo>GetUserInfo(){...} method.
So the question is this: How to set ViewBag properties on every action when data is retrieved using async/await.
MVC is not quite fully async-friendly, particularly with filters.
You could write your own RenderAsyncAction extension method or duplicate the code in all your async actions.
Alternatively, you could attempt a bit of a hack. I describe on my blog why using Result in ASP.NET can deadlock, but there's a workaround: use ConfigureAwait(false) on every await in GetUserInfo.
Then you can define a synchronous wrapper:
public UserInfo GetUserInfoBlocking()
{
return GetUserInfo().Result;
}
You should be able to use GetUserInfoBlocking in OnActionExecuting or RenderAction.
Please note the side effects:
This approach uses multiple threads per request, so this will decrease scalability. The pure async approach uses multiple requests per thread, so it increases scalability.
Any exceptions from GetUserInfo will be wrapped in an AggregateException, so be sure your logging will capture the InnerException details or you'll get meaningless errors in your logs.
It's definitely best to use async all the way down instead of blocking like this. But sometimes MVC doesn't leave you a choice (hopefully this will change in the future).

ASP.NET MVC 4 async child action

I have an ASP.NET MVC 4 application targeting .NET 4.5. One of our child actions makes a call out to a web service using HttpClient.
Since we're blocking on IO waiting for the HttpClient response, it makes a great deal of sense to convert the code to the async/await pattern. However, when MVC 4 attempts to execute the child action, we get the following error message:
HttpServerUtility.Execute blocked while waiting for an asynchronous operation to complete.
At first glance, it appears as though MVC 4 does not support async/await within a child action. The only remaining option is to run using synchronous code and force a "Wait" on the async task.
As we all know, touching .Result or .Wait() on an async task in an ASP.NET context will cause an immediate deadlock. My async logic is wrapped in a class library, so I can't use the "await blah.ConfigureAwait(false)" trick. Remember, tagging "async" on the child action and using await causes an error, and that prevents me from configuring the await.
I'm painted into a corner at this point. Is there any way to consume async methods in an MVC 4 child action? Seems like a flat out bug with no workarounds.
There are still parts of MVC that aren't async-friendly; I hope these will be addressed in the future. Please do create a Connect or UserVoice issue for this.
My async logic is wrapped in a class library, so I can't use the "await blah.ConfigureAwait(false)" trick.
You probably should add ConfigureAwait(false) to the calls in your class library (if you can).
You could also hack up an alternate solution. If your class library method doesn't need the ASP.NET context, then you could have a thread pool thread do the (a)waiting for you:
try
{
var result = Task.Run(async () => { await MyHttpRequest(...); }).Result;
}
catch (AggregateException ex) { ... }
The effect is similar to ConfigureAwait(false): since MyHttpRequest runs in a thread pool context, it will not attempt to enter the ASP.NET context when it completes.
The format of Stephen's answer didn't quite work for me (maybe it's an async noob problem, but hey).
I had to do write the async expression in this format to get a strongly typed return value.
Person myPerson = Task.Run(() => asyncMethodWhichGetsPerson(id)).Result;

Synchronization in ActionScript

Despite my best efforts, I am unable to produce the kind of synchronization effects I would like to in ActionScript. The issue is that I need to make several external calls to get various pieces of outside information in response to a user request, and the way items will be laid out on the page is dependent on what each of these external calls returns. So, I don't care that all of these calls return asynchronously. However, is there any way to force some amount of synchronization on ActionScript, so that at least calling the method for doing the final layout and placement of items on the page is dependent on all of my calls finishing?
If I understand the question right, event listeners are probably your best bet. Most loader classes throw an Event.COMPLETE message when they finish doing everything behind the scenes. If you wrote those external calls, it would be easy to dispatch a complete event at the end.
So when you make all these external calls, have a function that listens to when those calls complete. This function would keep track of how many calls have been made, and when there's none left to run, continue building your layout.
Rough Sketch to explain below:
var numProcesses:int = 0;
slowthing.addEventListener(Event.COMPLETE,waitForSlowest);
numProcesses++;
slowthing.load();
quickThing.addEventListener(Event.COMPLETE,waitForSlowest);
numProcesses++;
quickthing.load();
function waitForSlowest(e:Event)
{
numProcesses--;
if(numProcesses == 0)
finalizeLayout();
}

Resources