首页 > 图书中心 > .NET并发编程实战

前言

前    言

你可能正在阅读这本《.NET并发编程实战》,因为你希望构建速度极快的应用程序,或者想学习如何显著提高现有应用程序的性能。你关心性能,因为你致力于生成更快的程序,而且当代码中的一些更改使应用程序更快,响应更快时,你会感到兴奋。并行编程为对新开发技术充满热情的开发人员提供了无限的可能性。当需要考虑性能时,无论怎么强调在编程中使用并行的好处也不为过。但是,使用命令式和面向对象的编程风格来编写并发代码会很复杂,并引入了复杂性。因此,并发编程并没有被广泛地作为一种常见的实践所接受,这迫使程序员去寻找其他解决方案。

上大学的时候,我学习了函数式编程课程。那时,我学习的是Haskell,尽管该语言学习曲线很陡峭,难度很高,但是我很享受该课程的每一节课。因为我记得当我看到第一个例子时,对其解决方案的优雅以及简单而感到惊讶。15年后,当我开始寻找利用并发来增强我的程序的解决方案时,我又想起这些课程。这一次,我能够充分地认识到函数式编程在设计我的日常程序时的强大和有用。使用函数式编程风格存在一些益处,我将在《.NET并发编程实战》中对这些益处逐一进行讨论。

当时,我需要为医保行业构建一个软件系统,我的学术研究与专业工作在这里重合了。该项目需要开发一个应用程序去分析放射性医学图像。图像处理需要图像降噪、高斯算法、图像插值和图像滤波等几个步骤才能将颜色应用于灰度图像。该应用程序是使用Java开发的,最初能够按预期运行。但是后来该部门增加了需求,这种情况经常发生,这时问题就开始出现了。虽然软件没有任何问题或错误,但随着要分析的图像数量的增加,它变得更慢了。

当然,对这个问题提出的第一个解决方案是购买一个更强大的服务器。虽然在当时这是一个有效的解决方案,但是今天如果你购买一个新机器的目的是为了获得更快的CPU计算速度,你会感到失望的。这是因为现代CPU虽然有多个内核,但是其中单个内核的速度并不比2007年购买时的单个内核快。比购买新的服务器更好和更持久的替代方法是引入并行来利用多核硬件及其所有资源,从而最终加快图像处理。

从理论上讲,这是一项简单的任务,但是实际上并非如此。我必须学习如何使用线程和锁。遗憾的是,我在死锁方面获得了第一手经验。

这个死锁迫使我对应用程序的代码进行了大规模的修改。修改多到引入了bug,甚至与我做修改的原始目的无关。我很沮丧,这些代码是不可维护和脆弱的,整个过程很容易出现错误。我不得不在原来的问题上退一步,从不同的角度寻找解决方案。必须要有更好的办法。

我们使用的工具对我们的思维习惯产生深远的影响,因此也会影响我们的思维能力。

—Edsger Dijkstra

在花了几天时间寻找解决多线程错乱失控问题的解决方案后,我找到了答案。我所研究和阅读的一切都指向函数式范式。多年前我在大学课堂上学到的准则现在成为我前进的机理。我使用函数式语言重写图像处理应用程序的核心以应用并行运行。从命令式过渡到函数式最初是一个挑战。我几乎忘记了我在大学中学到的一切,所以我并不自豪地说,在这次经历中,我所编写的代码在函数式语言中看起来是非常面向对象的,但总体来说这是个成功的决定。新程序的编译和运行具有显著的性能改进,硬件资源得到了完全利用并且毫无错误。另外,一个意想不到的惊喜是,函数式编程导致代码行的数量显著减少: 比使用面向对象语言的原始实现减少了近50%。

这次经历让我重新考虑OOP是否适合作为解决所有编程问题的答案。我意识到这种编程模型和解决问题的方法视野有限。我这次进入函数式编程的旅程就是始于对良好的并发编程模型的要求。

从此之后,我对应用于多线程和并发的函数式编程产生了浓厚的兴趣。在看到复杂问题和问题根源时,我就会想到这些问题在函数式编程中的解决方案,函数式编程是一个功能强大的工具,可以使用可用的硬件来更快地运行。我开始欣赏这门学科是如何以一种连贯的、可组合的、漂亮的方式来编写并发程序的。

我第一次产生写这本书的想法是在 2010年7月,那时微软推出F# 并将其作为Visual Studio 2010的一部分。那时我对业界的趋势就已经很清楚了,越来越多的主流编程语言支持函数式,包括 C#、C++、Java和Python。2007年,C# 3.0引入了头等函数和新的构造(如lambda表达式和类型推断),从而引入函数式编程概念,并且很快就出现了允许声明式编程风格的语言集成查询(Language Integrate Query,LINQ)。

.NET平台已经融入了函数式世界。随着F#的引入,Microsoft拥有了同时支持面向对象和函数式范式的功能齐全的语言。此外,像C#这样的面向对象语言变得越来越混合了,弥合了不同编程模式之间的差距,从而允许这两种编程风格共存。

此外,我们正面临着多核时代,在这个时代里,CPU能力是以可用内核的数量来衡量的, 而不是以每秒的时钟周期来衡量的。有了这一趋势之后,单线程应用程序将无法在多核系统上实现更高的速度,除非该应用程序集成了并行性并使用算法将工作分散到多个内核上。

现在已经很清楚了,多线程是必需的,这个观点点燃了我把这种编程方法带给你的热情。《.NET并发编程实战》结合了并发编程和函数式范式的强大功能,并使用C#和F#语言来编写可读的、更模块化的和可维护的代码。你的代码将受益于这些技术,以更少的代码在最佳性能下运行,从而提高工作效率和程序的弹性。

开始开发多线程代码是一个激动人心的时刻。在这个过程中,软件公司比以往任何时候都更需要合适的工具和技术以便在不需要做出妥协的情况下选择对应的正确编程风格。在学习并行编程的过程中,最开始的挑战将会很快地减少,而对你毅力的回报则是无限的。

无论你的专业领域是什么,无论你是后端开发人员还是前端Web开发人员,无论你是开发基于云的应用程序或视频游戏,使用并行来获得更好的性能并构建可扩展的应用程序,这点都将一直存在。

《.NET并发编程实战》将描述我运用函数式编程使用C#和F#编写.NET并发程序的经验。我相信函数式编程正在成为编写并发代码,协调.NET中的异步和并行程序的实际方式,《.NET并发编程实战》将为你提供你所需的一切知识,从而让你做好准备并投身这个令人兴奋的多核计算机编程领域。

版权所有(C)2023 清华大学出版社有限公司 京ICP备10035462号 京公网安备11010802042911号

联系我们 | 网站地图 | 法律声明 | 友情链接 | 盗版举报 | 人才招聘