7

好吧,让我试着用句子来表达......

让我们考虑一个例子,我创建一个async方法并用await关键字调用它,据我所知,

  1. 主线程将被释放
  2. 在单独的线程中,异步方法将开始执行
  3. 一旦它被执行,指针将从它留在主线程中的最后一个位置恢复。

问题1:它会回到主线程还是一个新线程?

问题 2:如果 async 方法受 CPU 限制或网络限制,有什么区别吗?如果是,是什么?

重要的问题

问题 3:假设这是一个 CPU 密集型方法,我实现了什么?我的意思是 - 主线程被释放,但同时,另一个线程从线程池中使用。重点是什么 ?

4

3 回答 3

9

async不启动新线程。也没有await。我建议您阅读我的async介绍文章并跟进底部的资源。

async不是关于并行编程;这是关于异步编程的。如果您需要并行编程,请使用任务并行库(例如,PLINQ,Parallel或 - 在非常复杂的情况下 - raw Tasks)。

例如,您可以有一个async执行 I/O 绑定操作的方法。在这种情况下不需要另一个线程,也不会创建任何线程。

如果您确实有一个受 CPU 限制的方法,那么您可以使用它Task.Run来创建一个Task在线程池线程上执行该方法的可等待对象。例如,您可以await Task.Run(() => Parallel...);将一些并行处理视为异步操作。

于 2013-09-26T16:10:15.183 回答
4
  1. 调用者和async方法的执行将完全在当前线程上。async方法不会创建新线程,并且 usingasync/await实际上不会创建额外的线程。相反,线程完成/回调与同步上下文和暂停/给予控制(想想 Node.js 风格的编程)一起使用。但是,当控制权被发送或返回到await语句时,它可能最终位于不同的完成线程上(这取决于您的应用程序和其他一些因素)。

  2. 是的,如果它受 CPU 或网络限制,它会运行得更慢。因此await将需要更长的时间。

  3. 好处不在于线程信不信由你……异步编程并不一定意味着多线程。async好处是您可以在等待结果之前继续做其他不需要结果的工作async......一个例子是Web服务器HTTP侦听器线程池。如果你有一个大小为 20 的池,那么你的限制是 20 个并发请求......如果所有这些请求都花费 90% 的时间等待数据库工作,那么你可以async/await让数据库工作,并且await数据库结果回调的时间将被释放...线程将返回到 HTTP 侦听器线程池,另一个用户可以访问您的站点,而原来的用户正在等待数据库工作完成,从而提高了您的总限制。

它实际上是关于释放等待外部绑定和缓慢操作的线程以在这些操作执行时执行其他操作......利用内置线程池。

于 2013-09-26T16:12:24.863 回答
1

不要忘记异步部分可能是一些长期运行的工作,例如通过网络运行巨大的数据库查询,从互联网下载文件等。

于 2013-09-26T16:18:42.157 回答