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

相關文章
相關標籤/搜索