C# 中的异步陷阱

  • Jonathan Allen
  • 李彬

2013 年 5 月 6 日

话题:C#语言 & 开发

有时候,理解一种语言中的缺陷的最好方式是查看另一种语言如何防止这些缺陷发生。《Real-World Functional Programming》(注:该书已由清华大学出版社引进,中文名《C# 与 F# 编程实践》)的作者 Tomas Petricek 讨论了异步 C# 代码中常见的 7 项错误,并说明 F# 如何降低这些缺陷出现的可能性。

以下是 Tomas 的文章《在 C# 和 F# 中使用异步:C# 中的异步陷阱》所覆盖内容的简要介绍,而我们更鼓励读者阅读整篇文章。

Async没有异步运行:只有在第一个 await 语句之后出现的代码才会异步运行。

忽略结果:忘记 await 一个函数返回的任务,将会导致乱序执行。

Async void方法:不能 await 一个返回“async void”而不是“async Task”的异步函数,这会导致与上一条相同的问题。

Async void lambda函数:发生在当某个函数接收一个 Action 委托而不是 Func<…,Task> 委托的时候。此外也无法 await 一个 async 函数。

嵌套任务:在语句“await Task.Factory.StartNew(async () => { await Task.Delay(1000); });”中,第一个和第二个 await 语句互相之间完全无关。这意味着第一个 await 将在第二个 await 之前完成,而语句中关联的 1000ms 延迟将被忽略。

未按异步方式运行:使用 Task.Wait() 会将整个调用栈强制转为同步模式。

对那些不熟悉 F# 的开发者来说,在了解到 F# 中的 async 工作流并不是基于 Task 和 Task<T> 类型的时候或许会感到惊讶。相反,F# 使用自己的类型——Async<T>。

查看英文原文:Asynchronous Gotchas in C#


感谢姚琪琳对本文的审校。

给 InfoQ 中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ)或者腾讯微博(@InfoQ)关注我们,并与我们的编辑和其他读者朋友交流。

C#语言 & 开发