我为何喜欢用C#来作并发编程

(此文章同时发表在本人微信公众号“dotNET每日精华文章”,欢迎右边二维码来关注。)html

题记:就语言和运行时层面,C#作并发编程一点都不弱,缺的是生态和社区。git

硅谷才女朱赟(个人家门)昨天发了一篇文章《为何用 Java —— 关于并发编程》,让你们学习了Java中如何进行并发编程的一些基本知识。做为一个将近15年的.NET程序员,我以为有必要给你们补充介绍一下C#进行并发编程的知识(固然不会太深刻讲解)。这篇文章无心进行技术比较,毕竟技术只是工具(大同小异,各有千秋),主要仍是看用工具的人。程序员

并发(英文Concurrency),实际上是一个很泛的概念,字面意思就是“同时作多件事”,不过方式有所不一样。在.NET的世界里面,并发通常涉及以下几个方面:github

  1. 多线程编程(已过期,不介绍)
  2. 异步编程
  3. 并行编程
  4. 响应式编程
  5. 数据流编程

为了支持以上编程,.NET提供了不少基础功能,好比:委托,匿名函数,Lambda表达式,线程池,Task模型,支持并发的集合(线程安全集合和不可变集合) ,调度器,同步功能。在这里,就不对这些内容进行介绍了,你们能够自行搜索学习。另外,对于Actor模型,.NET中也有支持,但我不认为它属于语言/运行时层面的并发,它更像架构层面的并发,我最后会简单介绍。编程

1,异步编程

异步编程就是使用future模式(又称promise)或者回调机制来实现(Non-blocking on waiting)。promise

若是使用回调或事件来实现(容易callback hell),不只编写这样的代码不直观,很快就容易把代码搞得一团糟。不过在.NET 4.5(C# 5)中引入的async/await关键字(在.NET 4.0中经过添加Microsoft.Bcl.Async包也可使用),让编写异步代码变得容易和优雅。经过使用async/await关键字,能够像写同步代码那样编写异步代码,全部的回调和事件处理都交给编译器和运行时帮你处理了。安全

使用异步编程有两个好处:不阻塞主线程(好比UI线程),提升服务端应用的吞吐量。因此微软推荐ASP.NET中默认使用异步来处理请求。服务器

要详细了解异步编程,能够参考官方文档:https://msdn.microsoft.com/en-us/library/jj152938(v=vs.110).aspx和《Async in C# 5.0》这本书。另外,在这个官方文档中,微软还特地把异步编程分做了3种不一样的模型:基于任务的模式(TAP)就是我上面推荐的这种,基于事件的模式(EAP)和异步编程模型(APM)我上面不推荐的事件和回调。微信

2,并行编程

并行编程的出现其实是随着CPU有多核而兴起的,目的是充分利用多核CPU的计算能力。并行编程因为会提升CPU的利用率,更适合客户端的一些应用,对于服务端的应用可能会形成负面影响(由于服务器自己就具备并行处理的特色,好比IIS会并行的处理多个请求)。我本身使用并行编程最多的场景是以前分析环境数据不肯定度的时候,使用并行的方式计算蒙特卡洛模拟(计算上千次以后拟合),固然后来我使用泰勒级数展开来计算不肯定度,没有这么多的计算量就无需并行了。固然在计算多方案结果比较的状况下,仍是继续使用了并发计算。多线程

在.NET中,并行的支持主要靠.NET 4.0引入的任务并行库和并行LINQ。经过这些库能够实现数据并行处理(处理方式相同,输入数据不一样,好比我上面提到的应用场景)或者任务并行处理(处理方式不一样,且数据隔离)。经过使用并行处理库,你不用关心Task的建立和管理(固然更不用说底层的线程了),只须要关注处理任务自己就好了。

具体的用法仍是参考官方文档:https://msdn.microsoft.com/en-us/library/dd460693(v=vs.110).aspx,固然《Parallel Programming with Microsoft .NET》这本书也行。

3,响应式编程

响应式编程最近成为了一个Buzzword,其实微软6年前就开始给.NET提供一个Reactive Extensions了。一开始要理解响应式编程有点困难,可是一旦理解了,你就会对它的强大功能爱不释手。简单来讲,响应式编程把事件流看做数据流,不过数据流是从IEnumable中拉取的,而事件流是从IObservable推送给你的。为何响应式编程能够实现并发呢?这是由于Rx作到线程不可知,每次事件触发,后续的处理会从线程池中任意取出一个线程来处理。且能够对事件设置窗口期和限流。举个例子,你能够用Rx来让搜索文本框进行延迟处理(而不用相似我很早的时候用个定时器来延迟了)。

要详细了解Rx最好的方式就是浏览 IntroToRx.com 这个网站,固然还有官方文档:https://msdn.microsoft.com/en-us/data/gg577609

4,数据流编程

数据流(DataFlow)编程可能你们就更陌生了,不过仍是有些经常使用场景可使用数据流来解决。数据流实际上是在任务并行库(TPL)上衍生出来的一套处理数据的扩展(也结合了异步的特性),TPL也是处理并行编程中任务并行和数据并行的基础库。

望文生义,TPL DataFlow就是对数据进行一连串处理,首先为这样的处理定义一套网格(mesh),网格中能够定义分叉(fork)、链接(join)、循环(loop)。数据流入这样的处理网格就可以并行的被处理。你能够认为网格是一种升级版的管道,实际上不少时候就是被看成管道来使用。使用场景能够是“分析文本文件中词频”,也能够是“处理生产者/消费者问题”。

参考资料固然也是官方文档:https://msdn.microsoft.com/en-us/library/hh228603(v=vs.110).aspx

5,Actor模型

Scala有Akka,其实微软研究院也推出了Orleans来支持了Actor模型的实现,固然也有Akka.NET可用。Orleans设计的目标是为了方便程序员开发须要大规模扩展的云服务, 可用于实现DDD+EventSourcing/CQRS系统。

官方网站是:http://dotnet.github.io/orleans/,善友也有介绍:http://www.cnblogs.com/shanyou/p/4295523.html

那么,我为何喜欢使用C#来作并发编程呢?显而易见,有上面这些唾手可得的工具,使用C#一样能够轻易开发并发程序。

相关文章
相关标签/搜索