From the below examples I cannot understand why the async
and await
are not working in 1st example but working in 2nd example.
1st Example:
public static async Task Main(string[] args)
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
Console.WriteLine("started");
var i = await GetIntAsync(10);
var j = await GetstringAsync("abc");
Console.WriteLine($"int {i}, string {j}");
stopWatch.Stop();
Console.WriteLine("RunTime " stopWatch.ElapsedMilliseconds);
}
2nd Example:
public static async Task Main(string[] args)
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
Console.WriteLine("started");
var i = GetIntAsync(10);
var j = GetstringAsync("abc");
await i; await j;
Console.WriteLine($"int {i.Result}, string {j.Result}");
stopWatch.Stop();
Console.WriteLine("RunTime " stopWatch.ElapsedMilliseconds);
}
GetIntAsync
method:
public static async Task<int> GetIntAsync(int i)
{
Console.WriteLine("in get int waiting 3 sec's");
await Task.Run(() =>
{
Thread.Sleep(3000);
Console.WriteLine("int wait complete");
});
return i;
}
GetstringAsync
Method:
public static async Task<string> GetstringAsync(string i)
{
Console.WriteLine("in get int waiting 6 sec's");
await Task.Run(() =>
{
Thread.Sleep(6000);
Console.WriteLine("string wait complete");
});
return i;
}
CodePudding user response:
It seems you misunderstand what async
and await
does. Common misconception.
Async Await is NOT concurrency.
I suspect that you expect that GetIntAsync and GetstringAsync should be run in parallel.
In Rx Marble diagrams meaning:
---o
-------o
Where as you found:
---o
------o
Lets break down what you ACTUALLY wrote.
var i = await GetIntAsync(10);
var j = await GetstringAsync("abc");
Which can be expanded to:
var taskI = GetIntAsync(10);
var i = await taskI;
var taskJ = GetstringAsync("abc");
var j = await taskJ;
Notice that you start taskI, wait for its completion, THEN you start taskJ, THEN wait for that to complete.
Where as example 2 (after reformatting):
var taskI = GetIntAsync(10);
var taskJ = GetstringAsync("abc");
var i = await taskI;
var j = await taskJ;
Notice how ordering has changed.
FYI: You can also do
https://stackoverflow.com/a/40938652/1808494
public static class TaskEx
{
public static async Task<(T1, T2)> WhenAll<T1, T2>(Task<T1> task1, Task<T2> task2)
{
return (await task1, await task2);
}
}
var (i, j) = await TaskEx.WhenAll(
GetIntAsync(10),
GetstringAsync("abc"));