异步和等待 - 控制台、Windows表单和ASP.NET之间的区别

8

我一直在学习异步/等待的使用,并且我认为我已经理解了其背后的概念。然而,大多数 Channel 9 教程、MSDN 文章和 Stack Overflow 答案都是使用基于 GUI 的应用程序(Windows Forms 应用程序)来展示异步/等待的强大功能。

然而,在基于 UI 线程的应用程序与常规的线程池线程应用程序(例如 ASP.NET Web 应用程序、控制台应用程序等)中,我注意到异步/等待的使用存在根本性的差异。

由于在基于 UI 线程的应用程序中,UI 线程始终可用(除非进程被显式地停止或由 Windows 停止),因此负责执行任何异步方法中“等待”之后代码的线程池线程将保证找到 UI 线程以将结果返回(如果有的话)。

然而,在控制台应用程序或 ASP.NET Web 应用程序中,主线程(在控制台应用程序中)或 HTTP 请求(在 ASP.NET Web 应用程序中)必须等待(在某个时刻)直到所有异步操作完成。因此,如果没有其他工作要处理,异步方法调用后应该有 .Wait() 和 .Result 调用。

我的理解是否正确?我并不质疑异步对于 I/O 绑定或网络绑定操作的好处(我理解它将如何增加应用程序的可扩展性)。


1
值得注意的是,asyncawait关键字不会导致创建额外的线程。 - GSerg
1
在ASP.Net和异步方面,请查看在ASP.NET MVC中使用异步方法,所有适当的等待已经为您和您自己的代码进行了连接,不需要调用Wait/Result - Alexei Levenkov
@AlexeiLevenkov - 在MVC中(也适用于Windows窗体应用程序、ASP.NET Web表单应用程序),有一种方法可以使事件处理程序“异步”,.NET框架知道等待某些异步操作完成。在控制台应用程序中,主线程不能是异步的,它必须等待某些异步操作(即使是“fire & forget”类型的异步操作)完成后才能返回。 - IntelligentBinary
1个回答

9
在基于UI线程的应用程序中,UI线程始终可用(除非进程明确停止或由Windows停止),因此负责执行任何异步方法中“await”后面的代码的ThreadPool线程将保证找到UI线程以将结果返回(如果有)。
这有点混乱。没有迹象表明需要ThreadPool线程。
等待实现决定运行延续的位置,但通常使用当前的同步上下文来确定其运行位置:
- 在控制台应用程序中,根本没有同步上下文,因此将使用线程池线程进行延续。 - 在Windows Forms应用程序中,当您在UI线程上运行时,同步上下文是一个将在UI线程上执行代码的上下文...因此延续会在那里执行(除非使用ConfigureAwait等)。 - 在ASP.NET应用程序中,有一个特定于ASP.NET本身的同步上下文。
有关更多详细信息,请参见Stephen Cleary的MSDN文章

关于ASP.NET或控制台应用程序中必须调用WaitResult的问题,你的后续问题并不清楚...在这两种情况下,可能需要,但同样也可能不需要。这取决于你实际在做什么。不要忘记,即使是控制台应用程序也可以启动自己的线程并执行各种其他操作 - 例如,你可以在控制台应用程序中编写HTTP服务器...


1
附注:我认为在常规控制台应用程序中(没有计时器/消息循环/无限等待),至少会有一个Wait/Result,因为主函数是同步的,需要等待异步操作完成。实际上,如果在控制台应用程序中使用了其他机制(事件、计时器或甚至是Sleep...)来确保异步方法的执行完成,则不需要Wait/Result - Alexei Levenkov
@AlexeiLevenkov:可能有,也可能没有。这实际上取决于你想做什么。我不喜欢在没有更多上下文的情况下发表过多的笼统声明。 - Jon Skeet
谢谢Jon!在我的情况下,等待/结果是必需的,因为主方法在调用其所消耗的程序集的异步方法后没有其他工作要做。这将不适用于Windows窗体应用程序,甚至不适用于ASP.NET Web表单应用程序,因为事件处理程序可以是异步的(或者可以使用RegisterAsyncTask)。 - IntelligentBinary
@GSerg:对你来说,https://devblogs.microsoft.com/pfxteam/await-synchronizationcontext-and-console-apps/足够“官方”了吗?虽然这只是一篇博客文章,但是作者是负责团队的成员... - Jon Skeet
1
@GSerg:还要注意SynchronizationContext文档明确引用了我在这个答案中链接的MSDN文章。 - Jon Skeet
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接