Reputation: 109
I have async controller with async action. In the action I call WCF service method in SomeMethodOne (it needs 10 seconds to return result) and then I execute some mathematical operations in SomeMethodTwo (it executes about 6 seconds on my computer). As I understand during waiting on result from WCF service method, my computer should execute SomeMethodTwo but it doesn't and all code executes 10 seconds + 6 seconds = 16 seconds. Why?
public class TestController : AsyncController
{
public async Task<ActionResult> Index()
{
string result = await SomeMethodOne();
SomeMethodTwo();
return View();
}
private async Task<string> SomeMethodOne() // it needs 10 seconds to return result from WCF service
{
using (Service1Client client = new Service1Client())
{
return await client.GetDataAsync(5);
}
}
private void SomeMethodTwo() // it executes about 6 seconds on my computer
{
double result = 0;
for (int i = 0; i < 1000000000; i++)
{
result += Math.Sqrt(i);
}
}
}
The WCF service which I run locally:
public class Service1 : IService1
{
public string GetData(int value)
{
Thread.Sleep(10000);
return string.Format("You entered: {0}", value);
}
}
Upvotes: 1
Views: 1178
Reputation: 113342
and then I execute [emphasis mine]
Doing one thing and then doing another thing will take as long as both of them added together.
Doing two things at the same time might be quicker. It might be slower, because of context switching (imagine someone doing lots of "multitasking" and spending more time switching between them than working). It's likely it will be quicker here, if you don't have to get the results from the first action in order to do the second:
public async Task<ActionResult> Index()
{
Task<string> task = SomeMethodOne();
SomeMethodTwo();
string result = await task;
return View();
}
Obviously if you needed result
before you could call SomeMethodTwo()
then this wouldn't be possible. There is still an advantage on await
ing SomeMethodOne()
(which should be called SomeMethodOneAsync()
if possible to fit with .NET conventions), in that if GetDataAsync()
is truly async then the thread that was executing this action method can do something else for some other request to your web application, and another thread will pick up on dealing with this one when the I/O operation has returned data. This doesn't help the performance of the single method involved, but does help overall scalability of all the methods being run on the machine for all the web requests.
Upvotes: 1
Reputation: 457057
Your problem is that you're using await
right away:
string result = await SomeMethodOne();
The await
means that your controller action is going to "asynchronously wait" (await) for the result of SomeMethodOne
before it continues executing.
If you want to do asynchronous concurrency, then don't await
right away. Instead, you can start the asynchronous operation going by calling the method and then await
later:
public async Task<ActionResult> Index()
{
Task<string> firstOperation = SomeMethodOne();
SomeMethodTwo();
string result = await firstOperation;
return View();
}
Upvotes: 3