1,异步编程

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

如果使用回调或事件来实现(容易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, C#响应式远远把java甩在身后。

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#同样可以轻易开发并发程序。

【C# 并发编程】开端的更多相关文章

  1. [ 高并发]Java高并发编程系列第二篇--线程同步

    高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...

  2. 伪共享(false sharing),并发编程无声的性能杀手

    在并发编程过程中,我们大部分的焦点都放在如何控制共享变量的访问控制上(代码层面),但是很少人会关注系统硬件及 JVM 底层相关的影响因素.前段时间学习了一个牛X的高性能异步处理框架 Disruptor ...

  3. 【Java并发编程实战】----- AQS(四):CLH同步队列

    在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ...

  4. 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport

    在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 ...

  5. 【Java并发编程实战】----- AQS(二):获取锁、释放锁

    上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...

  6. 【Java并发编程实战】-----“J.U.C”:CLH队列锁

    在前面介绍的几篇博客中总是提到CLH队列,在AQS中CLH队列是维护一组线程的严格按照FIFO的队列.他能够确保无饥饿,严格的先来先服务的公平性.下图是CLH队列节点的示意图: 在CLH队列的节点QN ...

  7. 【Java并发编程实战】-----“J.U.C”:Exchanger

    前面介绍了三个同步辅助类:CyclicBarrier.Barrier.Phaser,这篇博客介绍最后一个:Exchanger.JDK API是这样介绍的:可以在对中对元素进行配对和交换的线程的同步点. ...

  8. 【Java并发编程实战】-----“J.U.C”:CountDownlatch

    上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一 ...

  9. 【Java并发编程实战】-----“J.U.C”:CyclicBarrier

    在上篇博客([Java并发编程实战]-----"J.U.C":Semaphore)中,LZ介绍了Semaphore,下面LZ介绍CyclicBarrier.在JDK API中是这么 ...

随机推荐

  1. Redis的几点积累

    1.Redis比memcache快 Redis具有事务,持久化等机制,但是它还能做到高性能,原因包括如下: Libevent.和Memcached不同,Redis并没有选择libevent.Libev ...

  2. 从容器镜像的选择-alpine 说起

    在 容器崛起之前,Alpine 还是个无名之辈,可能是因为大家并不是很关心操作系统本身的大小,毕竟大家只关心业务数据和文档,程序.库文件和系统本身的大小通常可以忽略不计. 容器技术席卷整个软件产业之后 ...

  3. golang中的pair

    package main import "fmt" type Reader interface { ReadBook() } type Writer interface { Wri ...

  4. .NET SourceGenerators 根据 HTTPAPI 接口自动生成实现类

    目录 摘要 元数据分析 使用 Source generators 实现 使用 Source generators 实现程序集分析 使用方法 SourceCode && Nuget pa ...

  5. SQL查询字段,起别名,列参与数学运算

    13.简单查询 13.1.查询一个字段? select 字段名 from 表名: 其中要注意: select和from都是关键字 字段名和表名都是标识符. 强调: 对于SQL语句说,是通用的 所有的S ...

  6. 什么是挂载?linux中挂载详解

    目录 一:什么是挂载,linux中挂载详解 一:什么是挂载,linux中挂载详解 1.linux中'一切皆文件',所有文件都放置在以根目录为树根的树形目录结构中.在linux看来,任何硬件设备也都是文 ...

  7. tmux 入门教程

    tmux 本教程是基于ACWing的<Linux基础课>所做,希望大家支持ACWing 功能 分屏 当需要同时运行两个终端,并且进行比对着输入时,来回切换比较麻烦,就可以利用分屏 可以在一 ...

  8. Spring源码-IOC部分-Bean实例化过程【5】

    实验环境:spring-framework-5.0.2.jdk8.gradle4.3.1 Spring源码-IOC部分-容器简介[1] Spring源码-IOC部分-容器初始化过程[2] Spring ...

  9. 计算机开放电子书 2021 RC2

    下载方式 pip install CDNDrive # 或 # pip install git+https://github.com/apachecn/CDNDrive cdrive download ...

  10. C程序:年转化天

    突然想算算自己到底活了多少天了,e,就是纯属为了好玩,毕竟咱作为一名C初学者还是要多练练的- 为了好玩,加了个密码登陆的,密码是521,还有就是不太懂时间获取... 具体闰年的判断方法: 代码如下: ...