好的,让我试着把它放在句子里......
让我们考虑一个例子,
在哪里创建async
方法并使用await
关键字调用它,
据我的知识告诉我,
问题1:它会回到主线程还是新线程?
问题2:如果异步方法是CPU绑定的还是网络绑定的,它会有什么不同吗?如果有,那是什么?
问题3:假设这是一个CPU绑定方法,我实现了什么?我的意思是 - 主线程已经发布,但同时,线程池中使用了另一个线程。有什么意义?
答案 0 :(得分:9)
async
无法启动新主题。 await
也没有。我建议您阅读我的async
intro post并跟进底部的资源。
async
不是关于并行编程;它是关于异步编程。如果需要并行编程,则使用任务并行库(例如,PLINQ,Parallel
或 - 在非常复杂的情况下 - 使用原始Task
s。。
例如,您可以使用async
方法执行I / O绑定操作。在这种情况下不需要另一个线程,也不会创建任何线程。
如果你有一个CPU绑定方法,那么你可以使用Task.Run
创建一个在线程池线程上执行该方法的等待Task
。例如,您可以执行类似await Task.Run(() => Parallel...);
的操作,将某些并行处理视为异步操作。
答案 1 :(得分:4)
执行调用者和async
方法将完全在当前线程上。 async
方法不会创建新线程,并且使用async/await
实际上不会创建其他线程。相反,线程完成/回调与同步上下文和挂起/给予控制一起使用(想想Node.js样式编程)。但是,当控件发出或返回到await
语句时,可能最终会出现在不同的完成线程上(这取决于您的应用程序和其他一些因素)。
是的,如果是CPU或网络绑定,它将运行得更慢。因此await
需要更长时间。
好处不在于线程是否相信......异步编程并不一定意味着多线程。好处是,在等待async
结果之前,您可以继续执行不需要async
结果的其他工作...示例是Web服务器HTTP侦听器线程池。如果您有一个大小为20的池,那么您的限制是20个并发请求...如果所有这些请求都花费90%的时间等待数据库工作,您可以async/await
数据库工作以及您在此期间的时间await
数据库结果回调将被释放...线程将返回到HTTP侦听器线程池,而另一个用户可以访问您的站点,而原始的一个等待数据库工作完成,增加您的总限制。
这就是释放等待外部绑定和慢速操作的线程,以便在这些操作执行时执行其他操作...利用内置线程池。
答案 2 :(得分:1)
不要忘记异步部分可能是一些长时间运行的工作,例如通过网络运行巨大的数据库查询,从互联网上下载文件等