Async Console Programs 异步控制台程序
如果你正在写一个控制台程序,你可能最终想要一个异步的main方法,像这样:
class Program { static async void Main(string[] args) { ... } }
很不幸,那个没用(实际上,VS 11 编译器拒绝异步Main方法)。我的这篇博客《Async and Await 异步和等待》里讲过,当异步方法完成后会返回到它的调用者。虽然这在UI应用(方法仅仅返回到UI事件循环)和ASP.NET(方法脱离线程返回但请求还是活着的【在生命周期内】)中运行很完美,但在控制台程序中不会工作得这么好:因为Main返回到操作系统,因此你的程序退出了。
你可以通过提供你自己的兼容异步上下文来变通一下。AsyncContext(异步上下文)是通用的上下文,它用来启用异步的MainAsync:
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) { ... } }
以下为一个较为常见的问题,望园友们注意!
问:关于使用".Wait()"来等待一个来自非异步的Main方法的异步方法,推荐使用AsyncContext吗?
答:在Main方法中要么使用AsyncContext,要么使用GetAwaiter().GetResult()。GetAwaiter().GetResult()本质上和Wait()一样,但是它没有把异常封装在AggregateException中。
AsyncContext在主控制台线程中装配了一个真实的单线程上下文。GetAwaiter().GetResult()将自由上下文默认保留在控制台应用中。如果我在写一个概念证明型的代码,并且最终在ASP.NET或者UI应用(具有单线程上下文)中终止,我通常就会使用AsyncContext;如果我在写一个真实的控制台应用,我可以任选一种方式。
如果您认为这篇文章还不错或者有所收获,您可以通过右边的“打赏”功能 打赏我一杯咖啡【物质支持】,也可以点击右下角的【好文要顶】按钮【精神支持】,因为这两种支持都是我继续写作,分享的最大动力!
作者:tkb至简
声明:原创博客请在转载时保留原文链接或者在文章开头加上本人博客地址,如发现错误,欢迎批评指正。凡是转载于本人的文章,不能设置打赏功能,如有特殊需求请与本人联系!
已将所有赞助者统一放到单独页面!签名处只保留最近10条赞助记录!查看赞助者列表
衷心感谢打赏者的厚爱与支持!也感谢点赞和评论的园友的支持! | |||
---|---|---|---|
打赏者 | 打赏金额 | 打赏日期 | |
微信:匿名 | 10.00 | 2017-08-03 | |
微信:匿名 | 10.00 | 2017-08-04 | |
微信:匿名 | 5.00 | 2017-06-15 | |
支付宝:一个名字499***@qq.com | 5.00 | 2017-06-14 | |
微信:匿名 | 16.00 | 2017-04-08 | |
支付宝:向京刘 | 10.00 | 2017-04-13 | |
微信:匿名 | 10.00 | 2017-003-08 | |
微信:匿名 | 5.00 | 2017-03-08 | |
支付宝:lll20001155 | 5.00 | 2017-03-03 | |
支付宝:她是一个弱女子 | 5.00 | 2017-03-02 |