Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to wait for async method to finish in C#?

For the following code (using EdgeJS module), I want to wait for asynchronous method Start to complete before writing sw.Elapsed, how should I do it?

using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using EdgeJs;
static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    /// 
    [STAThread]
    static  void Main()
    {
        //            Application.EnableVisualStyles();
        //            Application.SetCompatibleTextRenderingDefault(false);
        //            Application.Run(new Form1());

        Stopwatch sw =new Stopwatch();
        sw.Start();
        Task.Run((Action)Start).Wait();
        //wait for start to complete --- how should I do it??
        sw.Stop();
        Console.WriteLine(sw.Elapsed);
    }


    public static async void Start()
    {
        var func = Edge.Func(@"
        var esprima = require('esprima');
        var stringify = require('json-stable-stringify');

        var esprimaast = esprima.parse('var a=1;', { loc: true });
        var esprimaStr = stringify(esprimaast, { space: 3 });
        return function (data, callback) {
            callback(null, 'Node.js welcomes ' + esprimaStr);
        }
    ");

        Console.WriteLine(await func(".NET"));
        //Console.WriteLine("hello");
    }
}
like image 488
william007 Avatar asked Dec 20 '15 09:12

william007


People also ask

How do you wait for an async task to finish?

You will need to call AsyncTask. get() method for getting result back and make wait until doInBackground execution is not complete.

What happens if an async method is not awaited?

The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior isn't expected.

How long does async await wait?

Async Await makes execution sequential The above takes 100ms to complete, not a huge amount of time but still slow. This is because it is happening in sequence. Two promises are returned, both of which takes 50ms to complete.

Does async await stop execution?

The await expression causes async function execution to pause until a Promise is settled (that is, fulfilled or rejected), and to resume execution of the async function after fulfillment.


3 Answers

You can't await async void operations neither you should use async void except for async event handlers.

async void has several issues when you misuse it. exceptions thrown inside an async void won't be caught my regular means and will in most cases crash your application.

You should always use async Task or async Task<T> when you expect a return value.

See this MSDN post for a few guidelines with async/await.

like image 133
Tseng Avatar answered Oct 15 '22 17:10

Tseng


From this question you might use

sw.Start().GetAwaiter().GetResult;

or

Task.WaitAll(sw.Start());

Answers from Stephen Cleary and SnOrfus respectively. Hope it helps.

like image 41
user8675309 Avatar answered Oct 15 '22 16:10

user8675309


Well, the problem is that Everything originates from the synchronous Main() method. If you want to write asynchronous code then a good way to start would be to make an asynchronous Main method and write your programs code there instead (i answered a similar question recently).

class Program
{

    static void Main(string[] args)
    {
        Task mainTask = MainAsync(args);
        mainTask.Wait();
        // Instead of writing more code here, use the MainAsync-method as your new Main()
    }

    static async Task MainAsync(string[] args)
    {
        // Write your programs code here, You can freely use the async / await pattern
    }
}

That in combination with allowing your "Start" method to return a Task like this:

public static async Task Start()
{
    var func = Edge.Func(@"
        var esprima = require('esprima');
        var stringify = require('json-stable-stringify');

        var esprimaast = esprima.parse('var a=1;', { loc: true });
        var esprimaStr = stringify(esprimaast, { space: 3 });
        return function (data, callback) {
            callback(null, 'Node.js welcomes ' + esprimaStr);
        }
    ");

    Console.WriteLine(await func(".NET"));

    //Console.WriteLine("hello");
}

would allow you to call your Start method in the MainAsync method like this:

static async Task MainAsync(string[] args)
{
    Stopwatch sw = new Stopwatch();
    sw.Start();
    await Start();
    //wait for start to complete --- how should I do it??
    sw.Stop();
    Console.WriteLine(sw.Elapsed);
}

I have not been able to test this since i have no clue where that static "Edge" class comes from. But it's a good Place to start methinks.

like image 38
Shazi Avatar answered Oct 15 '22 17:10

Shazi