【发布时间】:2013-09-01 04:16:52
【问题描述】:
.net 4.5 的async-await 模式正在改变范式。好得令人难以置信。
我一直在将一些 IO 繁重的代码移植到 async-await,因为阻塞已成为过去。
很多人将 async-await 与僵尸感染进行比较,我发现它相当准确。异步代码喜欢其他异步代码(您需要一个异步函数才能等待异步函数)。所以越来越多的函数变得异步,这在你的代码库中不断增长。
将函数更改为异步是有些重复且缺乏想象力的工作。在声明中抛出一个async 关键字,用Task<> 包装返回值,你就大功告成了。整个过程如此简单令人不安,而且很快一个文本替换脚本将为我自动完成大部分“移植”。
现在的问题是.. 如果我的所有代码都慢慢变成异步的,为什么不默认全部异步?
我假设的明显原因是性能。 Async-await 有它的开销和不需要异步的代码,最好不要。但是,如果性能是唯一的问题,那么一些巧妙的优化肯定可以在不需要时自动消除开销。我已经阅读了有关 "fast path" 优化的信息,在我看来,它应该可以解决大部分问题。
也许这可以与垃圾收集器带来的范式转变相媲美。在早期的 GC 时代,释放自己的内存肯定更有效。但是大众仍然选择自动收集来支持更安全、更简单的代码,这些代码可能效率较低(甚至可以说不再正确)。也许这应该是这里的情况?为什么不应该所有函数都是异步的?
【问题讨论】:
-
感谢 C# 团队标记地图。就像几百年前做的那样,“龙卧于此”。你可以装备一艘船去那里,很可能你会在阳光普照和风在你背后的情况下幸存下来。有时没有,他们再也没有回来。就像 async/await 一样,SO 充满了来自不了解他们是如何脱离地图的用户的问题。尽管他们得到了很好的警告。现在是他们的问题,而不是 C# 团队的问题。他们标记了龙。
-
@Sayse 即使您消除了同步和异步函数之间的区别,同步实现的调用函数仍然是同步的(例如您的 WriteLine 示例)
-
“按任务包装返回值” 除非您的方法必须是
async(以履行某些合同),否则这可能是个坏主意。你得到了异步的缺点(方法调用的成本增加;在调用代码中必须使用await),但没有任何优点。 -
这是一个非常有趣的问题,但可能不太适合 SO。我们可能会考虑将其迁移到 Programmers。
-
也许我遗漏了一些东西,但我有完全相同的问题。如果 async/await 总是成对出现并且代码仍然必须等待它完成执行,那么为什么不只是更新现有的 .NET 框架,并让那些需要异步的方法 - 默认情况下是异步的,而不需要额外的关键字呢?该语言已经变成了它旨在逃避的东西 - 关键字意大利面条。我认为在建议使用“var”之后他们应该停止这样做。现在我们有了“动态”、异步/等待......等等......为什么你们不只是.NET-ify javascript? ;))
标签: c# .net asynchronous async-await