Concurrency in C# Cookbook
Asynchronous,Parallel,and Multithreaded Programming
Stephen Cleary
c#的并发烹饪书
异步,并行多线程编程
Stephen Cleary
Praise for Concurrency in C# Cookbook, Second Edition
c#的并发烹饪书第二版的表扬
“The next big thing in computing is making massive parallelism accessible to mere mortals. Developers have more power available to us than ever before, but expressing concurrency is still a challenge for many. Stephen turns his attention to this problem, helping us all better understand concurrency, threading,reactive programming models, parallelism, and much more in an easy-to-read but complete reference.”
Scott Hanselman, Principal Program Manager, ASP.NET and Azure Web Tools, Microsoft
“计算领域的下一件大事是让普通人也能访问大量并行。开发人员比以前有了更多的能力,但是表达并发性仍然是许多人的一个挑战。Stephen把他的注意力转向了这个问题,帮助我们更好地理解并发性,线程,响应式编程模型,并行性,以及更多易于阅读但完整的参考。”
Scott Hanselman, ASP的首席项目经理。NET和Azure Web工具,
微软
“The breadth of techniques covered and the cookbook format make this the ideal reference book for modern .NET concurrency.”
Jon Skeet, Senior Software Engineer at Google
所涵盖的技术的广度和指南使它成为现代.NET并发性的理想参考书。
Jon Skeet,谷歌的高级软件工程师
“Stephen Cleary has established himself as a key expert on asynchrony and parallelism in C#. This book clearly and concisely conveys the most important points and principles developers need to understand to get started and be successful with these technologies.”
Stephen Toub, Principal Architect, Microsoft
Stephen Cleary已经成为c#中异步和并行的关键专家。这本书清楚和简明地传达了最重要的点和原则,开发人员需要了解以开始和成功的使用这些技术。”
Stephen Toub,微软首席架构师
1 Preface 引言
I think the animal on this cover, a common palm civet, is applicable to the subject of this book. I knew nothing about this animal until I saw the cover, so I looked it up. Common palm civets are considered pests because they defecate all over attics and make loud noises fighting with each other at the most inopportune times. Their anal scent glands emit a nauseating secretion. They have an endangered species rating of “Least Concern,” which is apparently the politically correct way of saying, “Kill as many of these as you want; no one will miss them.” Common palm civets enjoy eating coffee cherries, and they pass the coffee beans through. Kopi luwak, one of the most expensive coffees in the world, is made from the coffee beans extracted from civet excretions.
我觉得这个封面上的动物,一个普通的麝香猫,很适合这本书的主题。在我看到封面之前,我对这种动物一无所知,所以我查了一下。麝香猫被认为是有害动物,因为它们在阁楼上到处大便,并在最不合时宜的时候发出很大的噪音,互相打架。它们的肛门嗅腺发出令人作呕的分泌物。它们被列为“最不受关注的濒危物种”,这显然是政治上正确的说法,“你想杀多少就杀多少;没有人会想念它们。“普通的麝香猫喜欢吃咖啡樱桃,它们会把咖啡豆传递出去。麝香猫咖啡是世界上最昂贵的咖啡之一,它的原料是从麝香猫的排泄物中提取的咖啡豆。
According to the Specialty Coffee Association of America, “It just tastes bad.” This makes the common palm civet a perfect mascot for concurrent and multithreaded development. To the uninitiated, concurrency and multithreading are undesirable. They make well-behaved code act up in the most horrendous ways. Race conditions and whatnot cause loud crashes (always, it seems, either in production or during a demo). Some have gone so far as to declare “threads are evil” and avoid concurrency completely. There are a handful of developers who have developed a taste for concurrency and use it without fear; but most developers have been burned in the past by concurrency, and that experience has left a bad taste in their mouth.
根据美国特色咖啡协会的说法,“它的味道很不好。“这使得普通的麝香猫成为并发和多线程开发的完美吉祥物。对于新手来说,并发和多线程是不受欢迎的。它们使行为良好的代码以最可怕的方式出现。竞态条件和其他因素会导致巨大的崩溃(游戏邦注:无论是在产品版本还是在演示版本中,似乎总是如此)。有些人甚至宣称“线程是邪恶的”,并完全避免并发。有少数开发人员已经开发了并发性,并无畏惧地使用它;但大多数开发人员在过去都曾被并发所困扰,这种经历给他们留下了不好的印象。
However, for modern applications, concurrency is quickly becoming a requirement. Users these days expect fully responsive interfaces, and server applications are having to scale to unprecedented levels. Concurrency addresses both of these trends.
然而,对于现代应用程序来说,并发性正迅速成为一种需求。如今,用户期望的是完全响应的界面,服务器应用程序必须扩展到前所未有的水平。并发性解决了这两种趋势。
Fortunately, there are many modern libraries that make concurrency much easier! Parallel processing and asynchronous programming are no longer exclusively the domains of wizards. By raising the level of abstraction, these libraries make responsive and scalable application development a realistic goal for every developer. If you have been burned in the past, when concurrency was extremely difficult, then I encourage you to give it another try with modern tools. We can probably never call concurrency easy, but it sure isn’t as hard as it used to be!
幸运的是,有许多现代的库使并发性变得更加容易!并行处理和异步编程不再仅仅是向导的领域。通过提高抽象级别,这些库使响应性和可伸缩的应用程序开发成为每个开发人员的现实目标。如果您在过去经历过并发性非常困难的情况,那么我鼓励您用现代工具再试一次。我们可能永远不会认为并发很容易,但它肯定不像以前那么难了!
1.1 Who Should Read This Book 谁应该读这本书
This book is written for developers who want to learn modern approaches to concurrency. I do assume that you’ve got a fair amount of .NET experience, including an understanding of generic collections, enumerables, and LINQ. I do not expect that you have any multithreading or asynchronous programming knowledge. If you do have some experience in those areas, you may still find this book helpful because it introduces newer libraries that are safer and easier to use.
这本书是为那些想要学习现代并发方法的开发人员编写的。我假定您已经有相当多的.NET 经验,包括对泛型集合、可枚举对象和LINQ的理解。我不期望您有任何多线程或异步编程知识。如果您确实在这些领域有一些经验,您可能仍然会发现这本书很有帮助,因为它介绍了更安全、更容易使用的新库。
Concurrency is useful for any kind of application. It doesn’t matter whether you work on desktop, mobile, or server applications; these days concurrency is practically a requirement across the board. You can use the recipes in this book to make user interfaces more responsive and servers more scalable. We are already at the point where concurrency is ubiquitous, and understanding these techniques and their uses is essential knowledge for the professional developer.
并发性对于任何类型的应用程序都很有用。不管你是在台式机、移动设备还是服务器上工作;如今,并发性实际上是一个全面的需求。你可以使用这本书中的方法使用户界面响应更快,服务器更可伸缩。我们已经到了并发无处不在的地步,理解这些技术及其用法是专业开发人员的基本知识。
1.2 Why I Wrote This Book 我为什么写这本书
Early in my career, I learned multithreading the hard way. After a couple of years, I learned asynchronous programming the hard way. While those were both valuable experiences, I do wish that back then I had some of the tools and resources that are available today. In particular, the async and await support in modern .NET languages is pure gold.
在我职业生涯的早期,我花了很大的力气才学会了多线程。几年后,我用艰苦的方式学习了异步编程。虽然这些都是宝贵的经验,但我确实希望当时我能拥有一些今天可用的工具和资源。特别是,现代.NET语言中的async和await支持是纯金的。
However, if you look around today at books and other resources for learning concurrency, they almost all start by introducing the most low-level concepts.
然而,如果您查看今天学习并发的书籍和其他资源,它们几乎都是从介绍最底层的概念开始的。
There’s excellent coverage of threads and serialization primitives, and the higher-level techniques are put off until later, if they’re covered at all. I believe this is for two reasons. First, many developers of concurrency, such as myself, did learn the low-level concepts first, slogging through the old-school techniques. Second, many books are years old and cover now-outdated techniques; as the newer techniques have become available, these books have been updated to include them, but have unfortunately placed them at the end. I think that’s backward. In fact, this book only covers modern approaches to concurrency. That’s not to say there’s no value in understanding all the lowlevel concepts.
文中对线程和序列化原语进行了很好的介绍,如果要介绍更高级的技术,则将其推迟到以后。我认为这有两个原因。首先,许多并发开发人员,比如我自己,确实首先学习了底层的概念,并费力地使用了老式的技术。其次,许多书都有好几年的历史了,而且涵盖了现在已经过时的技术;随着新技术的出现,这些书已经更新到包括它们,但不幸的是把它们放在了最后。我认为这是逆向的。事实上,这本书只涵盖了现代的并发方法。这并不是说理解所有的低级概念没有价值。
When I went to college for programming, I had one class where I had to build a virtual CPU from a handful of gates, and another class that covered assembly programming. In my professional career, I’ve never designed a CPU, and I’ve only written a couple dozen lines of assembly, but my 7 understanding of the fundamentals still helps me every day. Still, it’s best to start with the higher-level abstractions; my first programming class wasn’t in assembly language. This book fills a niche: it is an introduction to (and reference for) concurrency using modern approaches. It covers several different kinds of concurrency,including parallel, asynchronous, and reactive programming. It does not,however, cover any of the old-school techniques, which are adequately covered in many other books and online resources.
当我上大学学习编程的时候,有一门课是我必须用一些门来构建一个虚拟CPU,还有一门课是关于汇编编程的。在我的职业生涯中,我从未设计过CPU,我只写过几十行汇编,但我对基本原理的7个理解仍然每天帮助我。不过,最好还是从更高层次的抽象开始;我上的第一节编程课不是汇编语言。这本书填补了一个空白:它是使用现代方法的并发性的介绍(和参考)。它涵盖了几种不同类型的并发性,包括并行、异步和响应式编程。但是,它没有涵盖任何老派的技术,这些技术在许多其他书籍和在线资源中都有充分的介绍。
1.3 Navigating This Book 本书大纲
Here’s how the book is broken down:
这本书是这样分解的:
Chapter 1 is an introduction to the various kinds of concurrency covered by this book: parallel, asynchronous, reactive, and dataflow.
第1章介绍了本书涉及的各种并发:并行、异步、响应式和数据流。
Chapters 2–6 are a more thorough introduction to these kinds of concurrency.
第2-6章对这些并发性进行了更全面的介绍。
The remaining chapters each deal with a particular aspect of concurrency,and they act as a reference for solutions to common problems.
其余各章分别讨论并发性的一个特定方面,并作为常见问题解决方案的参考。
I recommend reading (or at least skimming) the first chapter, even if you’re already familiar with some kinds of concurrency.
我建议您阅读(或者至少略读)第一章,即使您已经熟悉了某些类型的并发。
警告
As this book goes to press, .NET Core 3.0 is still in beta, so some details around asynchronous streams may change.
在这本书出版的时候,. net Core 3.0还在测试阶段,所以一些关于异步流的细节可能会改变。
1.3.1 Online Resources 线上资源
This book acts like a broad-spectrum introduction to several different kinds of concurrency. I’ve done my best to include techniques that I and others have found the most helpful, but this book isn’t exhaustive by any means. The following resources are the best ones I’ve found for a more thorough exploration of these technologies:
这本书对几种不同类型的并发性进行了广泛的介绍。我已经尽了最大的努力,包括我和其他人认为最有帮助的技术,但这本书并不详尽。下面的资源是我找到的对这些技术进行更深入探索的最佳资源:
- For parallel programming, the best resource I know of is Parallel Programming with Microsoft .NET by Microsoft Press, the text of which is 8 available online. Unfortunately, it’s already a bit out of date. The section on futures should use asynchronous code instead, and the section on pipelines should use Channels or TPL Dataflow.
至于并行编程,我所知道的最好的资源是由Microsoft Press出版的《与Microsoft .NET并行编程》(parallel programming with Microsoft .NET)。不幸的是,它已经有点过时了。期货一节应该使用异步代码,管道一节应该使用通道或TPL数据流。
- For asynchronous programming, MSDN is quite good, particularly the “Asynchronous Programming” overview.
对于异步编程,MSDN是相当不错的,特别是“异步编程”概述。
- Microsoft has also made available documentation for TPL Dataflow.
微软也为TPL数据流提供了可用的文档。
- System.Reactive (Rx) is a library that is gaining a lot of traction online and continues evolving. In my opinion, the best resource today for Rx is Introduction to Rx, an ebook by Lee Campbell.
系统。Reactive (Rx)是一个在网络上受到广泛关注并不断发展的库。在我看来,目前关于Rx最好的资源是Lee Campbell的电子书《Rx is Introduction to Rx》。
1.3.2 Conventions Used in This Book 这本书中使用的惯例
The following typographical conventions are used in this book:
本书采用了下列印刷规范:
- Italic:Indicates new terms, URLs, email addresses, filenames, and file extensions.
斜体:表示新的术语、url、邮件地址、文件名和文件扩展名。
- Constant width:Used for program listings, as well as within paragraphs to refer to program elements such as variable or function names, databases, data types,environment variables, statements, and keywords.
常量宽度:用于程序列表,以及在段落中引用程序元素,如变量或函数名、数据库、数据类型、环境变量、语句和关键字。
- Constant width bold:Shows commands or other text that should be typed literally by the user.
常量粗体宽度:显示命令或其他应该由用户按字面输入的文本。
- Constant width italic:Shows text that should be replaced with user-supplied values or by values determined by context.
固定宽度斜体:显示应该用用户提供的值或由上下文确定的值替换的文本。
1.3.3 Using Code Examples 使用代码示例
Supplemental material (code examples, exercises, etc.) is available for download at https://oreil.ly/concur-c-ckbk2.
补充材料(代码示例、练习等)可以从以下网站下载 https://oreil.ly/concur-c-ckbk2.
This book is here to help you get your job done. In general, if example code is offered with this book, you may use it in your programs and documentation.You do not need to contact us for permission unless you’re reproducing a significant portion of the code. For example, writing a program that uses several chunks of code from this book does not require permission. Selling or distributing a CD-ROM of examples from O’Reilly books does require permission. Answering a question by citing this book and quoting example code does not require permission. Incorporating a significant amount of example code from this book into your product’s documentation does require permission.
这本书可以帮助你完成你的工作。一般来说,如果本书提供了示例代码,你可以在你的程序和文档中使用它。您不需要联系我们获得许可,除非您正在复制代码的重要部分。例如,编写一个使用本书中的几块代码的程序并不需要得到许可。销售或分发O 'Reilly books的示例光盘需要获得许可。通过引用这本书和引用示例代码来回答问题不需要获得许可。将本书中的大量示例代码合并到您的产品文档中需要获得许可。
We appreciate, but do not require, attribution. An attribution usually includes the title, author, publisher, and ISBN. For example: “Concurrency in C# Cookbook, Second Edition, by Stephen Cleary (O’Reilly). Copyright 2019 Stephen Cleary, 978-1-492-05450-4.”
我们欣赏,但不要求,归因。署名通常包括书名、作者、出版商和国际标准书号。例如:“c#的并发烹饪书,第二版,作者是Stephen Cleary (O 'Reilly)。版权所有2019 Stephen Cleary, 978-1-492-05450-4。
If you feel your use of code examples falls outside fair use or the permission given above, feel free to contact us at permissions@oreilly.com.
如果您觉得您对代码示例的使用超出了合理使用范围或超出了上述许可范围,请随时通过permissions@oreilly.com与我们联系。
1.3.4 O’Reilly Online Learning O’Reilly线上学习
Our unique network of experts and innovators share their knowledge and expertise through books, articles, conferences, and our online learning platform. O’Reilly’s online learning platform gives you on-demand access to live training courses, in-depth learning paths, interactive coding environments,and a vast collection of text and video from O’Reilly and 200+ other publishers. For more information, please visit http://oreilly.com.
我们独特的专家和创新者网络通过书籍、文章、会议和我们的在线学习平台分享他们的知识和专业知识。O 'Reilly的在线学习平台为您提供实时培训课程、深度学习路径、交互式编码环境以及来自O 'Reilly和200多家其他出版商的大量文本和视频集合的按需访问。欲了解更多信息,请访问http://oreilly.com。
1.3.5 How to Contact Us 如何联络我们
Please address comments and questions concerning this book to the publisher:
请向出版商提出关于这本书的评论和问题:
1.3.6 Acknowledgments 致谢
This book simply would not exist without the help of so many people!First and foremost, I’d like to acknowledge my Lord and Savior, Jesus Christ.Becoming a Christian was the most important decision of my life! If you want more information on this subject, feel free to contact me via my personal web page.
如果没有这么多人的帮助,这本书就不会存在。首先,我要感谢我的主和救世主,耶稣基督。成为一名基督徒是我一生中最重要的决定!如果你想了解更多关于这个主题的信息,请通过我的个人网页与我联系。
Second, I thank my family for allowing me to give up so much time with them.When I started writing, I had some author friends of mine tell me, “Say goodbye to your family for the next year!” and I thought they were joking. My wife, Mandy, and our children, SD and Emma, have been very understanding while I put in long days at work followed by writing on evenings and weekends. Thank you so much. I love you!
第二,我感谢我的家人让我放弃这么多和他们在一起的时间。当我开始写作的时候,我的一些作家朋友告诉我,“明年和你的家人说再见吧!”我以为他们是在开玩笑。我的妻子曼迪,还有我们的孩子,SD和Emma,在我白天工作,晚上和周末写作的时候,他们都非常理解我。非常感谢。我爱你!
Of course, this book wouldn’t be nearly as good as it is without my editors and our technical reviewers: Stephen Toub, Petr Onderka (“svick”), Nick Paldino (“casperOne”), Lee Campbell, and Pedro Felix. So if any mistakes get through, it’s totally their fault. Just kidding! Their input has been invaluable in shaping (and fixing) the content, and any remaining mistakes are of course my own.
当然,如果没有我的编辑和技术评论员:斯蒂芬·图布(Stephen Toub)、彼得·昂德卡(Petr Onderka)(《斯维克》(svick))、尼克·帕尔迪诺(Nick Paldino)(《卡斯佩龙》(casperOne))、李·坎贝尔(Lee Campbell)和佩德罗·费利克斯(Pedro Felix),这本书就不会这么好。所以如果出现任何错误,那都是他们的错。只是开个玩笑!他们的输入对内容的塑造(和修改)是无价的,而剩下的错误当然是我自己的。
Particular thanks go to Stephen Toub, who taught me the Boolean Argument Hack (Recipe 14.5), as well as countless other async topics; and Lee Campbell, who has helped me learn System.Reactive and make my observable code more idiomatic.
特别感谢Stephen Toub,他教了我布尔参数Hack (Recipe 14.5),以及无数其他的异步主题;还有李·坎贝尔,他帮助我学习系统。使我的可观察代码更加习惯化。
Finally, I’d like to thank some of the people I’ve learned these techniques from:Stephen Toub, Lucian Wischik, Thomas Levesque, Lee Campbell, the members of Stack Overflow and the MSDN forums, and the attendees of the software conferences in and around my home state of Michigan. I appreciate being a part of the software development community, and if this book adds any value, it’s because so many have already shown the way. Thank you all!
最后,我想感谢一些我从他们那里学到了这些技术的人:Stephen Toub, Lucian Wischik, Thomas Levesque, Lee Campbell, Stack Overflow和MSDN论坛的成员,以及在我的家乡密歇根州及其周边的软件会议的与会者。我很感激能成为软件开发社区的一员,如果这本书有任何价值的话,那是因为很多人已经展示了方法。谢谢大家!