若是你正在寫一個控制檯程序,你可能最終想要一個異步的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