简体   繁体   English

如何等待异步方法在C#中完成?

[英]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? 对于下面的代码(使用EdgeJS模块),我想在编写sw.Elapsed之前等待异步方法Start完成,我应该怎么做?

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");
    }
}

You can't await async void operations neither you should use async void except for async event handlers. 您不能等待async void操作,除了异步事件处理程序之外,您都不应该使用async void

async void has several issues when you misuse it. 当你滥用它时, async void有几个问题。 exceptions thrown inside an async void won't be caught my regular means and will in most cases crash your application. async void抛出的异常将不会被我的常规手段捕获,并且在大多数情况下会使应用程序崩溃。

You should always use async Task or async Task<T> when you expect a return value. 当您期望返回值时,应始终使用async Taskasync Task<T>

See this MSDN post for a few guidelines with async / await . 有关async / await的一些指导,请参阅此MSDN帖子

Well, the problem is that Everything originates from the synchronous Main() method. 好吧,问题是Everything来自同步Main()方法。 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 ). 如果你想编写异步代码,那么一个好的开始方法是创建一个异步的Main方法并在那里编写你的程序代码( 我最近回答了类似的问题 )。

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: 允许你在MainAsync方法中调用你的Start方法,如下所示:

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. 我无法测试这个,因为我不知道静态“Edge”类的来源。 But it's a good Place to start methinks. 但这是开始思考的好地方。

From this question you might use 这个问题你可以使用

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

or 要么

Task.WaitAll(sw.Start());

Answers from Stephen Cleary and SnOrfus respectively. 分别来自Stephen ClearySnOrfus的答案。 Hope it helps. 希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM