异步和等待 - 控制台,Windows窗体和ASP.NET之间的区别

Int*_*ary 8 .net c# asynchronous async-await

我一直在教自己异步/等待使用,我想我理解了引擎盖下的概念.但是,在async/await上的大多数Channel 9教程,MSDN文章和Stack溢出答案都使用基于GUI的应用程序(Windows Forms应用程序)来演示async/await的强大功能.

但是,我注意到基于UI线程的应用程序与常规ThreadPool基于线程的应用程序(例如ASP.NET Web应用程序,控制台应用程序等)中async/await使用的根本区别.

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

但是,在控制台应用程序或ASP.NET Web应用程序中,主线程(在控制台应用程序中)或HTTP请求(在ASP.NET Web应用程序中)必须等待(在一个时间点),直到所有异步操作都是完成.所以在Async方法调用之后应该有.Wait()和.Result调用,如果没有其他工作可以处理的话.

这种理解是否正确?我并没有质疑对I/O绑定或网络绑定操作进行异步的好处(我理解它将如何提高应用程序的可伸缩性).

Jon*_*eet 9

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

这有点困惑.没有迹象表明根本不需要ThreadPool线程.

这取决于等待执行以确定继续运行的位置,但通常使用当前同步上下文来确定运行它的位置:

  • 在一个控制台应用程序,也就是没有同步上下文,所以线程池线程用于延续.
  • 在Windows窗体应用程序中,当您在UI线程上运行时,同步上下文将在UI线程上执行代码...所以继续在那里执行(除非您使用ConfigureAwait,等等...)
  • 在ASP.NET应用程序中,有一个特定于ASP.NET本身的同步上下文.

有关详细信息,请参阅Stephen Cleary的MSDN文章.

目前还不清楚你后来的问题是什么意思,不得不打电话WaitResult在ASP.NET或控制台应用程序......在两种情况下可能都需要,但同样可能不是.这取决于你真正在做什么.不要忘记,即使是控制台应用程序也可以启动自己的线程并执行各种其他操作 - 例如,您可以在控制台应用程序中编写HTTP服务器...