【问题标题】:How to wait for async method to finish in C#?如何在 C# 中等待异步方法完成?
【发布时间】:2015-12-20 09:59:28
【问题描述】:

对于下面的代码(使用EdgeJS模块),我想等异步方法Start完成后再写sw.Elapsed,应该怎么做?

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

【问题讨论】:

  • 使 Start 方法返回 Task 而不是 void。然后你就可以轻松等待了-Start().Wait();
  • @SriramSakthivel 谢谢你的工作,考虑把它作为答案吗?

标签: c# asynchronous edgejs


【解决方案1】:

您不能等待async void 操作,也不能使用async void,异步事件处理程序除外。

async void 在您滥用它时会出现几个问题。 async void 中抛出的异常不会被我的常规手段捕获,并且在大多数情况下会使您的应用程序崩溃。

当您期望返回值时,您应该始终使用async Taskasync Task&lt;T&gt;

有关async/await 的一些指南,请参阅此MSDN post

【讨论】:

    【解决方案2】:

    来自this question你可能会使用

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

    Task.WaitAll(sw.Start());
    

    分别来自Stephen ClearySnOrfus 的回答。希望对您有所帮助。

    【讨论】:

      【解决方案3】:

      嗯,问题在于 Everything 源自同步 Main() 方法。如果您想编写异步代码,那么一个好的开始方法是创建一个异步 Main 方法并在那里编写您的程序代码 (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
          }
      }
      

      结合允许您的“开始”方法返回这样的任务:

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

      将允许您在 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);
      }
      

      我无法对此进行测试,因为我不知道静态“Edge”类的来源。但我认为这是一个很好的起点。

      【讨论】:

        猜你喜欢
        • 2013-02-15
        • 1970-01-01
        • 2013-08-19
        • 2023-03-16
        • 1970-01-01
        • 1970-01-01
        • 2019-10-19
        • 2014-08-09
        • 1970-01-01
        相关资源
        最近更新 更多