Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I call an async method in Main?

public class test
{
    public async Task Go()
    {
        await PrintAnswerToLife();
        Console.WriteLine("done");
    }

    public async Task PrintAnswerToLife()
    {
        int answer = await GetAnswerToLife();
        Console.WriteLine(answer);
    }

    public async Task<int> GetAnswerToLife()
    {
        await Task.Delay(5000);
        int answer = 21 * 2;
        return answer;
    }
}

if I want to call Go in main() method, how can I do that? I am trying out c# new features, I know i can hook the async method to a event and by triggering that event, async method can be called.

But what if I want to call it directly in main method? How can i do that?

I did something like

class Program
{
    static void Main(string[] args)
    {
        test t = new test();
        t.Go().GetAwaiter().OnCompleted(() =>
        {
            Console.WriteLine("finished");
        });
        Console.ReadKey();
    }


}

But seems it's a dead lock and nothing is printed on the screen.

like image 611
Larry Avatar asked Oct 21 '12 21:10

Larry


People also ask

How do you call async method?

The simplest way to execute a method asynchronously is to start executing the method by calling the delegate's BeginInvoke method, do some work on the main thread, and then call the delegate's EndInvoke method. EndInvoke might block the calling thread because it does not return until the asynchronous call completes.

Can main method be async?

From C# 7.1, it is also possible to define the Main method as async with any of the following additional overloads. static Task Main(); static Task < int > Main(); static Task Main(string[] args); static Task < int > Main(string[] args); An async Main method enables you to use await in your Main method.

How do you call async method without await?

However, just to address "Call an async method in C# without await", you can execute the async method inside a Task. Run . This approach will wait until MyAsyncMethod finish. await asynchronously unwraps the Result of your task, whereas just using Result would block until the task had completed.


3 Answers

Your Main method can be simplified. For C# 7.1 and newer:

static async Task Main(string[] args)
{
    test t = new test();
    await t.Go();
    Console.WriteLine("finished");
    Console.ReadKey();
}

For earlier versions of C#:

static void Main(string[] args)
{
    test t = new test();
    t.Go().Wait();
    Console.WriteLine("finished");
    Console.ReadKey();
}

This is part of the beauty of the async keyword (and related functionality): the use and confusing nature of callbacks is greatly reduced or eliminated.

like image 91
Tim S. Avatar answered Oct 17 '22 07:10

Tim S.


Instead of Wait, you're better off using new test().Go().GetAwaiter().GetResult() since this will avoid exceptions being wrapped into AggregateExceptions, so you can just surround your Go() method with a try catch(Exception ex) block as usual.

like image 41
arviman Avatar answered Oct 17 '22 06:10

arviman


Since the release of C# v7.1 async main methods have become available to use which avoids the need for the workarounds in the answers already posted. The following signatures have been added:

public static Task Main();
public static Task<int> Main();
public static Task Main(string[] args);
public static Task<int> Main(string[] args);

This allows you to write your code like this:

static async Task Main(string[] args)
{
    await DoSomethingAsync();
}

static async Task DoSomethingAsync()
{
    //...
}
like image 27
DavidG Avatar answered Oct 17 '22 08:10

DavidG