Reputation: 307
I'm new to C# and for now I'm trying to understand async/await feautures. So I have created small sandbox app:
namespace sandbox
{
public class Test
{
public async Task<string> GetItemsAsync()
{
var a = await Task1();
var b = await Task2();
var c = await Task3();
return a + b + c;
}
public string GetItems()
{
return _T1() + _T2() + _T3();
}
private readonly int cycles = 100000000;
private async Task<string> Task1()
{
return await Task.Factory.StartNew(_T1);
}
private async Task<string> Task2()
{
return await Task.Factory.StartNew(_T2);
}
private async Task<string> Task3()
{
return await Task.Factory.StartNew(_T3);
}
// long running operation
private string _T1()
{
for (int i = 0; i < cycles; i++) ;
for (int i = 0; i < cycles; i++) ;
return "One";
}
// long running operation
private string _T2()
{
for (int i = 0; i < cycles; i++) ;
for (int i = 0; i < cycles; i++) ;
return "Two";
}
// long running operation
private string _T3()
{
for (int i = 0; i < cycles; i++) ;
for (int i = 0; i < cycles; i++) ;
return "Three";
}
}
class Program
{
static void Main(string[] args)
{
var t = new Test();
Console.WriteLine("Async");
Stopwatch sw = new Stopwatch();
sw.Start();
var result = t.GetItemsAsync();
Console.WriteLine(result.Result);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
Console.WriteLine("Sync");
sw.Restart();
var strResult = t.GetItems();
Console.WriteLine(strResult);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
Console.ReadLine();
}
}
}
But the result is weird:
Async
OneTwoThree
1754
Sync
OneTwoThree
1506
Async method runs longer than similar sync one. For me it's look like async methods runs synchronously but I cant figure out why.
Upvotes: 0
Views: 426
Reputation: 269
I suspect the intention was to make all three tasks do the job in parallel. That is one of options how it could be accomplished:
public async Task<string> GetItemsAsync()
{
var a = Task1();
var b = Task2();
var c = Task3();
return string.Concat(await Task.WhenAll(a, b, c));
}
Upvotes: 1
Reputation: 391664
Because of this:
var a = await Task1();
var b = await Task2();
var c = await Task3();
Before you even start Task2
you have waited for Task1
to complete. So you're not running them in parallel, you're running them in sequence.
If you want to start all 3 tasks, then wait for them to complete you would have to change this method to this:
public async Task<string> GetItemsAsync()
{
var t1 = Task1();
var t2 = Task2();
var t3 = Task3();
var a = await t1;
var b = await t2;
var c = await t3;
return a + b + c;
}
Or just the last part:
return (await t1) + (await t2) + (await t3);
Additionally, this code is an antipattern:
private async Task<string> Task3()
{
return await Task.Factory.StartNew(_T3);
}
You don't need async/await
here because you're not doing any more work in this method after your sub-task returns.
Instead simply rewrite this method (and its siblings) to this:
private Task<string> Task3()
{
return Task.Factory.StartNew(_T3);
}
Upvotes: 4