async/await 是否适合同时受 IO 和 CPU 限制的方法?

2023-12-30

MSDN 文档似乎指出async and await适用于 IO 密集型任务,而Task.Run应该用于 CPU 密集型任务。

我正在开发一个应用程序,该应用程序执行 HTTP 请求来检索 HTML 文档,然后对其进行解析。我有一个看起来像这样的方法:

public async Task<HtmlDocument> LoadPage(Uri address)
{
    using (var httpResponse = await new HttpClient().GetAsync(address)) //IO-bound
    using (var responseContent = httpResponse.Content)
    using (var contentStream = await responseContent.ReadAsStreamAsync())
        return await Task.Run(() => LoadHtmlDocument(contentStream)); //CPU-bound
}

这是好的和合适的使用吗async and await,还是我过度使用它了?


已经有两个很好的答案了,但要加上我的 0.02...

如果你说的是消耗异步操作,async/await非常适合 I/O 密集型和 CPU 密集型。

我认为 MSDN 文档确实有轻微的倾向生产异步操作,在这种情况下你确实想使用TaskCompletionSource(或类似)用于 I/O 绑定和Task.Run(或类似)用于 CPU 限制。一旦你创建了初始的Task包装,最好consumed by async and await.

对于您的特定示例,这实际上取决于多少时间LoadHtmlDocument会采取。如果您删除Task.Run,您将在调用的同一上下文中执行它LoadPage(可能在 UI 线程上)。 Windows 8 指南规定任何耗时超过 50 毫秒的操作都应执行async...请记住,开发人员计算机上的 50 毫秒可能在客户端计算机上更长...

所以如果你能保证LoadHtmlDocument运行时间不到50ms,直接执行即可:

public async Task<HtmlDocument> LoadPage(Uri address)
{
  using (var httpResponse = await new HttpClient().GetAsync(address)) //IO-bound
  using (var responseContent = httpResponse.Content)
  using (var contentStream = await responseContent.ReadAsStreamAsync()) //IO-bound
    return LoadHtmlDocument(contentStream); //CPU-bound
}

不过,我会推荐ConfigureAwait正如@svick提到的:

public async Task<HtmlDocument> LoadPage(Uri address)
{
  using (var httpResponse = await new HttpClient().GetAsync(address)
      .ConfigureAwait(continueOnCapturedContext: false)) //IO-bound
  using (var responseContent = httpResponse.Content)
  using (var contentStream = await responseContent.ReadAsStreamAsync()
      .ConfigureAwait(continueOnCapturedContext: false)) //IO-bound
    return LoadHtmlDocument(contentStream); //CPU-bound
}

With ConfigureAwait,如果 HTTP 请求没有立即(同步)完成,那么这将(在这种情况下)导致LoadHtmlDocument在线程池线程上执行,无需显式调用Task.Run.

如果您有兴趣async在这个级别的表现,你应该看看 Stephen Toub 的video http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-829T and MSDN 文章 http://msdn.microsoft.com/en-us/magazine/hh456402.aspx就此主题而言。他有大量有用的信息。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

async/await 是否适合同时受 IO 和 CPU 限制的方法? 的相关文章

随机推荐

  • XMPP可以像Comet的http long wait那样使用吗?

    Can XMPP http en wikipedia org wiki Extensible Messaging and Presence Protocol以类似的方式应用反向阿贾克斯 http en wikipedia org wiki
  • C++ 运行时 N 个嵌套向量

    在 C 中 有或没有 boost 如何创建 N 维向量 其中 N 在运行时确定 大致如下 PROCEDURE buildNVectors int n std vector lt n dimensional std vector gt str
  • C# 中的 setjmp/longjmp。是否可以?

    当我需要转到本地范围时 我遇到了一个问题 if DoSomethingHere if goto Label else if Label DoSomethingHereToo 这在 C 中显然是不可能的 是的 我知道使用 goto 被认为是一
  • 检查 div 是否确实溢出和/或有滚动条

    我们有一个页面 div style height 400px div 滚动条时也是如此 因此仅此一项不会削减它 编辑 你们太快了 谢谢 我会研究这些建议 再次感谢 if myDiv 0 scrollHeight gt myDiv inner
  • MVC4如何动态添加行项目到EditorFor字段?

    我有一个包含迭代项目的视图模型 我通过 EditorFor 方法将它们放置在我的视图中 View model Models MyModel using Html BeginForm Model Action Model Controller
  • C# 中按大小错误对文件进行排序

    我在排序文件时遇到了一些问题 我的程序应该允许我按大小和日期对目录中的文件进行排序 日期工作正常 但当我尝试按大小排序时 它返回错误 这是我的相关代码 if orden Equals tam ficheroo dirInfoo GetFil
  • 手动使 C# 线程超时

    我需要为长时间运行的线程添加超时 我们遇到一些外部问题 有时会导致该线程无限期地挂在某一行代码处 为了使我们的进程更加健壮 我们希望检测线程不再主动运行 轮询并中止该线程 这将使我们清理资源并重新启动线程 添加此功能的首选方法是什么 首选方
  • ARM Linux 上的“回溯已停止:前一帧与此帧相同(堆栈损坏?)”

    我正在尝试在 Linux ARM 架构 上运行应用程序时调试段错误 我复制了核心转储文件并尝试在 x86 64 主机上使用arm gdb 获取回溯 这是o p arm arago linux gnueabi gdb test slave6
  • 用于Linux内核开发的发行版[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 这是学习 Linux 内核开发的最佳轻量级发行版 它应该有很多可用的调试和分析工具 LFS http
  • 在react-native上使用styled-components,如何计算组件的高度?

    使用样式组件 我需要根据屏幕尺寸计算组件的高度 如下所示 const ForgotPasswordContainer styled View height calc 100 20px 这样使用是不行的 样式组件不支持基于百分比的高度值 使用
  • 确定链接服务器的 SQL Server 版本

    这里有人知道我如何通过使用 TSQL 语句来确定链接服务器上运行的 SQL 版本吗 我正在运行 SQL2005 我的链接服务器正在运行 sql2000 2005 和 2008 的混合 select from openquery MyLink
  • 从 ANTLR 生成 EBNF

    有人知道从 ANTLR 生成 EBNF 的工具吗 ANTLR 已经接近 EBNF 但出于文档目的 我希望有一个干净的 EBNF 描述 中间没有代码 有了antlrworks 就可以得到语法图了 java cp antlrworks 1 1
  • NSEvent 和 Magic Mouse

    如何区分事件是否发生 void scrollWheel NSEvent event是由魔术鼠标或触控板触发的吗 我问这个问题的原因是因为我想在使用触控板时为滚动事件分配不同的操作 因为用户可以在触控板上捏合缩放 然而 在魔术鼠标上 用户无法
  • 如何监听使用 Chrome 开发者工具所做的 DOM 更改

    我需要制作一个应用程序 可以检测我何时使用 chrome 开发人员工具更新网页上的属性 例如 如果我打开开发人员工具 请使用元素选择器并更改特定元素的字体大小 见图 我应该能够运行一个程序 通知该程序更新了页面上的哪些元素以及更改了哪些属性
  • R:X 错误中的 NA/NaN/Inf

    我正在尝试使用 R 执行负二项式回归 当我执行以下命令时 DV2 25112013 nb lt glm nb DV2 25112013 Bcorp Geographic Proximity Dirty Industry Clean Indu
  • 在 Windows 上为“therubyracer”安装“libv8”gem

    我安装时遇到问题therubyracerWindows 上的宝石 Using Ruby 2 1 6 32 bit和跑步 gem install libv8 v 3 16 14 3 with system v8 这是我得到的错误 Instal
  • 为什么这段代码会出现空指针异常?我认为字符类可以处理 null 被分配? [复制]

    这个问题在这里已经有答案了 public class Playground public static void main String args String s blah Character lclfs s contains s con
  • 在 Linux 上将 Android Studio 设置重置为默认设置

    每个人 我曾经在 Mac 上开发 Android 应用程序 最近我在运行Xubuntu的Thinkpad上安装了android开发环境 我通过文件 gt 导入设置将Mac上的Android studio设置导入到Xubuntu上的Andro
  • 堆栈变量与堆变量

    我的想法是否正确 char buff 500 创建一个堆栈变量 并且 char buff char malloc 500 创建一个堆变量 如果这是正确的 那么何时以及为什么要使用堆变量而不是堆栈变量 反之亦然 我知道堆栈更快还有其他什么吗
  • async/await 是否适合同时受 IO 和 CPU 限制的方法?

    MSDN 文档似乎指出async and await适用于 IO 密集型任务 而Task Run应该用于 CPU 密集型任务 我正在开发一个应用程序 该应用程序执行 HTTP 请求来检索 HTML 文档 然后对其进行解析 我有一个看起来像这