Home > database >  Understanding Async and await in .Net
Understanding Async and await in .Net

Time:12-31

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"));
  • Related