I have set-up the examples from this MSDN article Using Asynchronous Methods in ASP.NET MVC 4 and have done some benchmarking to see what I come up with.
I set-up 2 controllers Sync
and Async
and did some testing using a loader tool for benchmarking. The loader tool just sends 50-60 constant requests for one minute. Each controller is calling the same webservice 3 times. The code for each is below:
public ActionResult Sync()
{
var g1 = GetGizmos("url1");
var g2 = GetGizmos("url2");
var g3 = GetGizmos("url3");
return Content("");
}
public object GetGizmos(string uri)
{
using (WebClient webClient = new WebClient())
{
return JsonConvert.DeserializeObject(
webClient.DownloadString(uri)
);
}
}
public async Task<ActionResult> Async()
{
var g1 = GetGizmosAsync("url1");
var g2 = GetGizmosAsync("url2");
var g3 = GetGizmosAsync("url3");
var a1 = await g1;
var a2 = await g2;
var a3 = await g3;
return Content("");
}
public async Task<object> GetGizmosAsync(string uri)
{
using (HttpClient httpClient = new HttpClient())
{
var response = await httpClient.GetAsync(uri);
return (await response.Content.ReadAsAsync<object>());
}
}
First question, does anyone know why Async is taking longer, running less and causing timeouts, whereas sync version isn't? I would think using Async for this would be faster, no timeouts, etc. Just doesn't seem right, am I doing something wrong here? What can be done to improve/fix it?
Second question, Using WebRequests in general, is there a way to speed that up? I have set the following in my global.asax
but still unsure if the usage is correct:
System.Net.ServicePointManager.DefaultConnectionLimit = 1000;
Also, any other suggestions to help speed up an application performing these types of tasts will be very helpful.
In general, you should make a method asynchronous if the synchronous method waits on the ASP.NET request thread while doing no work. By making the call asynchronous, the ASP.NET request thread is not stalled doing no work while it waits for the web service request to complete.
The asynchronous controller enables you to write asynchronous action methods. It allows you to perform long running operation(s) without making the running thread idle. It does not mean it will take lesser time to complete the action.
A traditional ASP.NET MVC control action will be synchronous by nature; this means a thread in the ASP.NET Thread Pool is blocked until the action completes. Calling an asynchronous controller action will not block a thread in the thread pool.
C# Language Async-Await Async/await will only improve performance if it allows the machine to do additional work.
webClient.DownloadString(uri)
to
var response = await httpClient.GetAsync(uri);
return (await response.Content.ReadAsAsync<object>());
maybe you can try
webclient.DownloadStringAsync(uri)
and you could optimize your async code to
await Task.Run(() => {
// just run your sync code here
var g1 = GetGizmos("url1");
var g2 = GetGizmos("url2");
var g3 = GetGizmos("url3");
return Content("");
});
It is enough to have one async yielding point here.
Refer to this answer for details about async: Do you have to put Task.Run in a method to make it async?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With