BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

Async/Await - 性能开销和其他陷阱

| 作者 Roopesh Shenoy 关注 0 他的粉丝 ,译者 姚琪琳 关注 0 他的粉丝 发布于 2013年7月26日. 估计阅读时间: 2 分钟 | QCon上海2018 关注大数据平台技术选型、搭建、系统迁移和优化的经验。

Async/Await是C# 5引入的最强大的语言特性。但有哪些陷阱需要注意呢?与这两个关键字相关的开销又有哪些?

MSDN上的一篇文章“异步编程最佳实践”强调了以下几点:

  • 选择异步Task方法而非异步void方法,事件处理程序除外。它们采用不同的错误处理语义。Marker Metro的Keith Patton详细解释了这一点
  • 避免混合使用阻塞和非阻塞代码,这可能会导致死锁、更加复杂的错误处理以及上下文线程的意外阻塞。
  • 如果后续代码不需要使用原始上下文,就用ConfigureAwait(false)来获得更好的性能。这会使后续代码运行在线程池上下文中。如果你不得不混合编写同步和异步的代码,它还可以避免死锁。注意,在服务端使用时会有略微不同的考虑

RedGate的软件工程师Chris Hurley解释了async-await的CPU开销,并通过一小段示例代码进行了演示:

  • 用async关键字调用一个方法,会创建一个状态机,并构建一个Task对象来包含要执行的工作,以及获取执行上下文和同步上下文。
  • 在该展示示例中,第一次调用共运行了963个框架方法,来初始化相对简单的async方法。
  • 上下文将被缓存,因此后续调用会减少很多开销。
  • 对于在很短的时间内(1毫秒)就能同步运行完的方法,异步开销将阻塞调用线程更长的时间。在示例中,调用线程解除阻塞差不多要用45毫秒的时间。即使在循环中,后续调用会大幅减少开销的情况下,调用线程也看不到任何性能优势。
  • 结论——避免对(耗时)短的方法使用async/await,避免在小循环内使用await语句(可以将整个循环放到一个async方法内)。

我们之前已经介绍过一些在使用这两个关键字时会遇到的其他常见陷阱

查看英文原文:Async/Await – Performance Overheads and Other Pitfalls

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

性能损失 by LI kidfruit

async方法如果不用wait,而是同步执行,应该性能没有损失

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

1 讨论

深度内容

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT