Async Console Programs 异步控制台程序

若是你正在写一个控制台程序,你可能最终想要一个异步的main方法,像这样:html

class Program
{
  static async void Main(string[] args)
  {
    ...
  }
}

很不幸,那个没用(实际上,VS 11 编译器拒绝异步Main方法)。个人这篇博客《Async and Await 异步和等待》里讲过,当异步方法完成后会返回到它的调用者。虽然这在UI应用(方法仅仅返回到UI事件循环)和ASP.NET(方法脱离线程返回但请求仍是活着的【在生命周期内】)中运行很完美,但在控制台程序中不会工做得这么好:由于Main返回到操做系统,所以你的程序退出了。 异步

你能够经过提供你本身的兼容异步上下文来变通一下。AsyncContext(异步上下文)是通用的上下文,它用来启用异步的MainAsync: async

class Program
{
  static int Main(string[] args)
  {
    try
    {
      return AsyncContext.Run(() => MainAsync(args));
    }
    catch (Exception ex)
    {
      Console.Error.WriteLine(ex);
      return -1;
    }
  }

  static async Task<int> MainAsync(string[] args)
  {
    ...
  }
}

如下为一个较为常见的问题,望园友们注意! spa

问:关于使用".Wait()"来等待一个来自非异步的Main方法的异步方法,推荐使用AsyncContext吗? 操作系统

答:在Main方法中要么使用AsyncContext,要么使用GetAwaiter().GetResult()。GetAwaiter().GetResult()本质上和Wait()同样,可是它没有把异常封装在AggregateException中。 线程

AsyncContext在主控制台线程中装配了一个真实的单线程上下文。GetAwaiter().GetResult()将自由上下文默认保留在控制台应用中。若是我在写一个概念证实型的代码,而且最终在ASP.NET或者UI应用(具备单线程上下文)中终止,我一般就会使用AsyncContext;若是我在写一个真实的控制台应用,我能够任选一种方式。 code

相关文章
相关标签/搜索