【问题标题】:Should we switch to use async I/O by default?我们应该切换到默认使用异步 I/O 吗?
【发布时间】:2012-10-09 06:07:09
【问题描述】:

凭借异步 I/O 的优势,现在编码和编写非常容易(使用 Await 和 TAP 方法)我想知道,我们是否应该默认使用异步,并且只在需要时使用同步来调整性能.

异步 ​​I/O 释放调用线程并允许在等待结果时执行其他操作。另一方面,异步 I/O 比同步慢一点。

为了强制执行响应式 UI,WinRT 设计人员发现提供仅异步方法是可以接受的。

AFAIK Windows 文件 I/O 内部是异步的。天真地看着这个我不清楚,为什么 .NET 中的异步文件 i/O 应该比同步慢。

我通常倾向于简单性和稳健性,并且只在必要时调整性能。过去,我们默认使用同步,但调用某些服务以及手机等平台强制执行异步除外。我们很少使用异步进行调整。

【问题讨论】:

  • pfxteam blog 在此上下文中包含一些有趣的信息:"请注意,我们没有添加粒度非常小的 API 的异步版本,例如 TextReader.Peek。原因是异步 API 也增加了一些开销,我们希望防止开发人员意外走错方向。这也意味着我们特别决定不为 BinaryReader 或 BinaryWriter 上的方法提供异步版本....

标签: .net asynchronous task-parallel-library


【解决方案1】:

在 C# 5 中使用异步 IO 变得非常容易,但仍然存在与之相关的生产力成本。例如,您需要在必要时在以前没有的地方添加新的关键字。您必须更改方法的返回类型。

如果您稍后决定某个方法应该执行 IO,则必须更改整个调用链以切换到异步。它是一种非本地的变化蔓延到其他模块。

您无法分析异步 IO。分析工具什么也没有。如果您暂停调试器,则任何线程堆栈上都没有任何内容。似乎没有人在做任何事情。那是因为异步 IO 不持有线程。它只是一个数据结构(内核中的一个对象)。

该决定还取决于应用程序类型。在 WinForms 或 WPF 应用程序中,我宁愿使用异步,因为它可以很好地集成到 UI 线程中。

在 ASP.NET/WCF 设置中,主要优点是在调用长时间运行的后端服务时不会耗尽线程池。如果你没有这样的问题,而且我认为这相当罕见,那么你从异步 IO 中获得的收益很少。实际上,默认情况下您会降低性能。

在 Metro 环境中,已为您做出决定。微软(合法地)选择以开发人员的生产力换取用户体验。

所以这不是一个明确的决定。在这一点上,利弊都相当薄弱。出于这个原因,我避免给出明确的建议。这在很大程度上取决于具体情况。

【讨论】:

    【解决方案2】:

    如果您有自然异步操作,我建议使用async,否则使用同步代码。 async 确实慢了一点,但在大多数情况下,它就像“打开悍马中的收音机”一样慢。

    在 UI 程序中,async 提高了响应能力。在服务器应用中,async 提高了可扩展性。

    AFAIK Windows 文件 I/O 内部是异步的。天真地看着这个我不清楚,为什么 .NET 中的异步文件 i/O 应该比同步慢。

    异步代码比较慢,因为它必须分配结构来跟踪异步操作;同步代码只使用当前线程(及其堆栈)。所以操作本身并没有变慢,但由于垃圾收集器的压力更大,总体速度会略有下降。

    我通常倾向于简单性和稳健性,并且只在必要时调整性能。

    我同意。如果您有一个自然异步的操作(例如 I/O),请公开一个async API。如果您有一个自然同步的操作,请公开一个同步 API。 Stephen Toub 在这方面有几篇很棒的博文(herehere)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-01
      • 2012-09-14
      • 1970-01-01
      • 2013-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-21
      相关资源
      最近更新 更多