无法在控制台应用程序的“主要”方法上指定“异步”修饰符

无法在控制台应用程序的“主要”方法上指定“异步”修饰符,第1张

无法在控制台应用程序的“主要”方法上指定“异步”修饰符

如您所见,在VS11中,编译器将禁止使用

async Main
方法。在VS2010中,使用Async CTP允许(但绝不建议这样做)。

我最近在博客文章中特别提到了异步/等待和异步控制台程序。以下是介绍性帖子中的一些背景信息:

如果“ await”看到awaitable尚未完成,则它将异步执行。它告诉等待的对象在完成时运行该方法的其余部分,然后从异步方法中 返回
。当等待方法将其余方法传递给等待方法时,它还将捕获当前 上下文

稍后,当awaitable完成时,它将执行async方法的其余部分(在捕获的上下文中)。

这就是在控制台程序中使用出现问题的原因

async Main

请记住,在我们的介绍性帖子中,异步方法将在完成之前 返回
其调用方。这在UI应用程序(该方法仅返回到UI事件循环)和ASP.NET应用程序(该方法从线程返回但使请求保持活动状态)中完美地工作。对于Console程序,效果不是很好:Main返回OS-
因此程序退出。

一种解决方案是提供您自己的上下文-异步兼容的控制台程序的“主循环”。

如果您有一台具有异步CTP的计算机,则可以

GeneralThreadAffineContext
从“ 我的文档” “ Microsoft Visual
Studio”中,使用“异步CTP” “样本(C#测试)”单元测试“ AsyncTestUtilities”

。或者,您可以
AsyncContext
从我的Nito.AsyncEx
NuGet包中使用。

这是一个使用

AsyncContext
; 的例子。
GeneralThreadAffineContext
具有几乎相同的用法:

using Nito.AsyncEx;class Program{    static void Main(string[] args)    {        AsyncContext.Run(() => MainAsync(args));    }    static async void MainAsync(string[] args)    {        Bootstrapper bs = new Bootstrapper();        var list = await bs.GetList();    }}

或者,您可以仅阻塞主控制台线程,直到异步工作完成:

class Program{    static void Main(string[] args)    {        MainAsync(args).GetAwaiter().GetResult();    }    static async Task MainAsync(string[] args)    {        Bootstrapper bs = new Bootstrapper();        var list = await bs.GetList();    }}

注意使用

GetAwaiter().GetResult()
;
这样可以避免
AggregateException
使用
Wait()
或时发生的换行
Result

更新,2017-11-30: 从Visual Studio 2017更新3(15.3)开始,该语言现在支持

asyncMain
-,只要它返回
Task
或即可
Task<T>
。因此,您现在可以执行以下 *** 作:

class Program{    static async Task Main(string[] args)    {        Bootstrapper bs = new Bootstrapper();        var list = await bs.GetList();    }}

语义似乎与

GetAwaiter().GetResult()
阻塞主线程的样式相同。但是,尚无C#7.1的语言规范,因此这只是一个假设。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5427601.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-11
下一篇 2022-12-11

发表评论

登录后才能评论

评论列表(0条)

保存