若是你正在写一个控制台程序,你可能最终想要一个异步的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