Search code examples
c#asynchronousasync-await

Call async method from another async method


I am trying to run an asynchronous method from another asynchronous method and make sure that both of them complete successfully. Like in the example below I am adding a delay of 1000ms in Function1() and a delay of 3000ms in Function2(), meaning the Main() task should complete first. Also, I am using .Net6.0 to able to run this snippet.

using System;
using System.Threading.Tasks;
using System.Threading;
                    
public class Program
{
    static async Task Main(string[] args)
    {
        var inst = new SomeClass();
        // inst.Functon1(); // Method is called but not waited till its completion
        await inst.Functon1(); // Seems this blocks this Main method itself
        Console.WriteLine("finished");
    }
}

public class SomeClass
{
    public async Task Functon1(){
        await Task.Delay(1000); // should have await to block
        Console.WriteLine("SomeClass In Func1");
        await Functon2();
    }
    
    private async Task Functon2(){
        await Task.Delay(3000);
        Console.WriteLine("SomeClass In Func2");
        await Functon3();
    }
    
    private async Task Functon3(){
        Console.WriteLine("SomeClass In Func3");
    }
}

Output should be like below, in the exact same order is the expectation. If await is removed from Main(), finished is only printed but not others.

finished
SomeClass In Func1
SomeClass In Func2
SomeClass In Func3

PS - I tried calling inst.Functon1() with .ConfigureAwait(true) and ConfigureAwait(false) but it made little difference in an async method.


Solution

  • Output should be like below, in the exact same order is the expectation.

    finished
    SomeClass In Func1
    SomeClass In Func2
    SomeClass In Func3
    

    It's not possible to get this output, because the console application terminates immediately after the completion of the Main entry point. The main thread of the console application is what keeps the process alive. As soon as the main thread has nothing else to do, and provided that no other foreground threads have been launched and are still alive, the process will terminate almost immediately. So you will not get any more output after the "finished" has been printed.

    I tried calling inst.Functon1() with .ConfigureAwait(true) and ConfigureAwait(false) but it made little difference in an async method.

    Actually it made no difference, not little difference. The ConfigureAwait affects the behavior of an await only when there is an ambient SynchronizationContext or an ambient non-default TaskScheduler. Console applications are equipped with neither of those, as you can confirm experimentally by printing the SynchronizationContext.Current and the TaskScheduler.Current. So the ConfigureAwait has absolutely no effect in your awaits here.