5

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");
    }
}
william007
  • 17,375
  • 25
  • 118
  • 194

3 Answers3

4

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.

Tseng
  • 61,549
  • 15
  • 193
  • 205
2

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.

user8675309
  • 591
  • 1
  • 6
  • 24
1

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.

Community
  • 1
  • 1
Shazi
  • 1,490
  • 1
  • 10
  • 22