Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么不应该';默认情况下,不是所有函数都是异步的吗?_C#_.net_Asynchronous_Async Await - Fatal编程技术网

C# 为什么不应该';默认情况下,不是所有函数都是异步的吗?

C# 为什么不应该';默认情况下,不是所有函数都是异步的吗?,c#,.net,asynchronous,async-await,C#,.net,Asynchronous,Async Await,NET4.5的模式正在改变。这太好了,简直难以置信 我一直在向async await移植一些IO密集型代码,因为阻塞已经成为过去 相当多的人将AsyncWait比作僵尸横行,我发现它相当准确。异步代码与其他异步代码类似(需要异步函数才能等待异步函数)。因此,越来越多的函数变得异步,这在您的代码库中不断增长 将函数更改为异步有点重复和缺乏想象力。在声明中抛出一个async关键字,用Task包装返回值,就基本完成了。整个过程有多容易令人不安,很快一个文本替换脚本将为我自动化大部分“移植” 现在的问题

NET4.5的模式正在改变。这太好了,简直难以置信

我一直在向async await移植一些IO密集型代码,因为阻塞已经成为过去

相当多的人将AsyncWait比作僵尸横行,我发现它相当准确。异步代码与其他异步代码类似(需要异步函数才能等待异步函数)。因此,越来越多的函数变得异步,这在您的代码库中不断增长

将函数更改为异步有点重复和缺乏想象力。在声明中抛出一个
async
关键字,用
Task
包装返回值,就基本完成了。整个过程有多容易令人不安,很快一个文本替换脚本将为我自动化大部分“移植”

现在的问题是。。如果我所有的代码都在慢慢地变为异步,为什么不在默认情况下将其全部变为异步呢

我认为最明显的原因是性能。Async await的开销和代码不需要异步,最好不需要。但是,如果性能是唯一的问题,那么一些巧妙的优化当然可以在不需要时自动消除开销。我读过关于优化的书,在我看来,只有它才能解决大部分问题

也许这可以与垃圾收集器带来的范式转变相媲美。在GC早期,释放自己的内存肯定更有效。但大众仍然选择自动收集,以支持更安全、更简单、效率更低的代码(甚至可以说,这已经不再是事实)。也许这里应该是这样?为什么不应该所有函数都是异步的

为什么不应该所有函数都是异步的

正如你提到的,性能是一个原因。请注意,您链接到的“快速路径”选项在完成任务的情况下确实提高了性能,但与单个方法调用相比,它仍然需要更多的指令和开销。因此,即使有了“快速路径”,每次异步方法调用都会增加很多复杂性和开销

向后兼容性以及与其他语言(包括互操作场景)的兼容性也将成为问题

另一个问题是复杂性和意图。异步操作增加了复杂性-在许多情况下,语言功能隐藏了这一点,但在许多情况下,使方法
异步
无疑会增加其使用的复杂性。如果没有同步上下文,尤其如此,因为异步方法很容易导致意外的线程问题

此外,还有许多例程本质上不是异步的。这些操作作为同步操作更有意义。例如,强制
Math.Sqrt
成为
Task Math.SqrtAsync
将是荒谬的,因为根本没有理由让它是异步的。而不是让
async
推送您的应用程序,您最终会得到
wait
到处传播

这也将彻底打破当前的范式,并导致属性(实际上只是方法对)出现问题。它们也会异步吗?),并在整个框架和语言的设计中产生其他影响


如果您正在做大量IO绑定的工作,您会发现普遍使用
async
是一个很好的补充,您的许多例程都是
async
。然而,一般来说,当你开始做CPU受限的工作时,使事情异步实际上并不好——它隐藏了这样一个事实,即你在一个看似异步但实际上并不一定真正异步的API下使用CPU周期。

除了性能之外,异步可能会降低生产率。在客户端(WinForms、WPF、Windows Phone)上,这有利于提高生产率。但是在服务器上,或者在其他非UI场景中,您需要支付生产率。在默认情况下,您肯定不想在那里使用异步。在需要可扩展性优势时使用它


在最合适的时候使用它。在其他情况下,不要这样做。

首先,谢谢你的客气话。这确实是一个很棒的功能,我很高兴成为它的一小部分

如果我所有的代码都在慢慢地变为异步,为什么不在默认情况下将其全部变为异步呢

嗯,你太夸张了all您的代码没有变为异步。当您将两个“普通”整数相加时,您不会等待结果。当你把两个未来的整数加在一起得到第三个未来的整数——因为这就是
任务
是什么,你将来要访问它——当然你可能会等待结果

不使所有内容都异步的主要原因是因为async/await的目的是在一个有许多高延迟操作的世界中更容易编写代码。绝大多数操作的延迟都不高,因此采取降低延迟的性能措施没有任何意义。相反,您的一些关键操作是高延迟的,这些操作会导致整个代码中异步的僵尸泛滥

如果性能是唯一的问题,那么一些巧妙的优化当然可以在不需要时自动消除开销

在理论上,理论和实践是相似的。实际上,它们从来都不是

让我给你三点反对这种先进行优化再进行转换的观点

第一点是:C#/VB/F#中的异步本质上是一种有限形式的连续传递。函数式语言社区中的大量研究已经找到了确定如何优化大量使用延续传递样式的代码的方法。编译器团队可能必须解决非常复杂的问题
M();
N();