我同意所有 comments ;这不是关于你对结果做什么以及什么时候做,而是关于在异步操作运行时,执行你的代码的线程被允许go 做什么.如果数据库中的内容是一个复杂的视图,基于一个需要5分钟才能运行的查询,那么任何内容都会阻塞您的线程5分钟.AnyAsync可以让该线程在这段时间内为您的Web服务器提供数以万计的请求.如果您已经阻止了一个线程,那么Web服务器将不得不启动另一个线程来为其他人服务,而且线程的成本很高.
Async不是"更好的性能",意思是"使其异步并运行更快"——代码以相同的速度执行.Async是关于"更好地利用资源"-你需要更少的线程,它们更忙/更少无所事事地等待IO完成
如果它是一间办公室,那就好比你在等电话的时候煮咖啡;想象一下,你接到煤气公司的电话,老板大喊着要喝杯咖啡.如果你是异步的,你会把它放在扬声器上,在等待的时候站起来煮咖啡,等待等待等待音乐停止的声音和煤气公司说"你好"的声音.如果你是同步的,你会坐在那里无视老板的要求,而其他人在煮咖啡(这意味着老板必须雇用其他人).让你坐在那里无所事事,只是等待,并且不得不雇用其他人,比让你在x工作到一定程度后再go 做其他事情要昂贵得多.如果你是异步的,你会在等待水壶沸腾的时候go 重新装满打印机.如果你正在等待同步,而初级办公室人员正在等待水壶烧开,老板将不得不雇佣另一个人来填充打印机..
当煤气公司最终让你休息时,是你还是其他人接听电话取决于你是否煮好了咖啡,是否有空,和/或你是否已配置等待,以表明必须由你接听电话(真),或办公室中是否有人可以继续(假)
备注:我将其与使用IEnumerable进行比较,然后立即使用例如Count(),这将遍历整个沙邦.在这种情况下,我们可以立即进行T[],而不会导致性能下降.你对此有什么 idea ?
这取决于你对结果还将做些什么.如果您需要反复询问结果的长度并随机访问它,请使用ToArrayAsync
将其转换为一个数组,然后将其作为本地缓存数据进行所有操作.除非结果是一个两TB大的查询????
如果您实际上只需要一次计数,那么将所有内存用于分配数组并获取其长度是没有意义的;只要做CountAsync
这两个问题似乎都与"异步还是否"的问题不完全相关如果您的IEnumerable来自一个缓慢的网络,并且是一个巨大而缓慢的查询,那么它仍然会返回到"让线程停止运行并忙于做其他事情,这样您就不必启动更多线程".请注意,这里的"慢"甚至可能意味着几十毫秒.我们不必讨论分钟操作,就可以看到异步的好处
非常快的操作当然,您可以进行同步,以节省设置状态机的微小成本,但要确定设置状态机的成本之间的临界点,以便线程可以执行其他操作,而不是让它等待一段时间;这台机器价格很低.面对这种 Select ,如果可用的话,我通常会 Select 异步,尤其是在涉及任何IO的情况下
如何证明/反驳是否重要.
每种情况下,你都必须赛马;op完成同步的速度有多快,执行异步状态管理需要多长时间.对于整个代码库来说,这样做可能会很令人厌烦,这就是为什么我倾向于继续"如果异步可用,并且不仅仅是为了异步,那么可能有人认为使用异步是明智的,所以我们应该使用它".如果您使用它在库中的存在作为您应该在代码中利用它的指标(然后向您的代码用户指示他们应该……),那么异步在整个代码库中传播可能是一件好事