在前两篇随笔中,先后介绍了 Thread 、ThreadPool 、IAsyncResult (即 APM系列) 、Task  、TPL (Task Parallel Library)。

写到这些笔者突然意识到 还有一个EMP系列没有写,在这里补充一下:

六、 EAP 、EAP中的典型代表是 WebClient:

EAP系列采用 ***Async方法 + ***Completed事件 的编码规范,不做太多解释、具体的demo如下:

            var address = "http://www.cnblogs.com/08shiyan/";WebClient client = new WebClient();Uri uri = new Uri(address);client.DownloadStringCompleted += new DownloadStringCompletedEventHandler((object sender, DownloadStringCompletedEventArgs e) =>{this.txtTip.SetTip("下载完成");});client.DownloadStringAsync(uri);this.txtTip.SetTip("开始异步下载数据");

七、PLINQ 、LINQ的并行版本

1) 首先看一下PLINQ在 MSDN 中的介绍 :

并行 LINQ (PLINQ) 是 LINQ 模式的并行实现。 PLINQ 查询在许多方面类似于非并行 LINQ to Objects 查询。 与顺序 LINQ 查询一样,PLINQ 查询对任何内存中 IEnumerable 或 IEnumerable<T> 数据源进行操作,并推迟执行,这意味着在枚举查询之前不会开始执行这些操作。 主要区别是 PLINQ 尝试充分利用系统中的所有处理器。 它利用所有处理器的方法是,将数据源分成片段,然后在多个处理器上对单独工作线程上的每个片段并行执行查询。 在许多情况下,并行执行意味着查询运行速度显著提高。

通过并行执行,PLINQ 通常只需向数据源添加 AsParallel 查询操作,即可在某些查询类型的旧版代码上获得显著的性能改进。 但是,并行可能引入其自己的复杂性,因此并非所有查询操作在 PLINQ 中都运行得更快。 事实上,并行降低了某些查询的速度。 因此,您应了解诸如排序等问题如何影响并行查询。 有关详细信息,请参阅 Understanding Speedup in PLINQ。

从介绍中、我们可以明确三点:

1、PLINQ是LINQ的并行版本、它拥有和LINQ一样一样强大的基因。

2、PLINQ会尝试充分利用所有处理器、(PLINQ在 MSDN 中的介绍 最多是64个),因此许多情况下PLINQ可以显著提高的并行效率,尤其是CPU密集型计算的并行率。

3、并非所有查询操作在 PLINQ 中都运行得更快。

2)PLINQ与LINQ的无缝连接

PLINQ 的实现基础是 :ParallelQuery<TSource>,LINQ的实现基础是:IEnumerable<TSource>, 当然这里说的都是泛型版本。

如下的两个扩展方法、可轻易实现PLINQ和LINQ间的转化。

public static ParallelQuery<TSource> AsParallel<TSource>(this IEnumerable<TSource> source);
public static IEnumerable<TSource> AsSequential<TSource>(this ParallelQuery<TSource> source);

3)简单Demo

        /// <summary>/// PLinq:Linq的并行版本/// </summary>public void Demo1(){Task.Run(() =>{var result = Enumerable.Range(1, 10).AsParallel().Where(e =>{SetTip("开始                      " + e);SetTip("休眠             " + e);Thread.Sleep(1000);SetTip("结束  " + e);return e > 5;});SetTip("打印结果");foreach (var item in result){SetTip(item.ToString());}SetTip("并行查询执行完毕");});}

4)PLINQ与LINQ的微妙关系

在功能上:PLINQ几乎实现了LINQ的全部功能、且方法名都是一致的。

在时间性能上:PLINQ will always attempt to execute a query at least as fast as the query would run sequentially.

  因此、PLINQ在执行查询之前会进行一次“预判”,如果发现了某些情况,当前可能会自动转为顺序执行、即LINQ模式。

5)当查询包含以下情况时,PLINQ将会默认按照顺序模式执行

  • 包含 Select 子句、已建立索引的 Where 子句、已建立索引的 SelectMany 子句或 ElementAt 子句的查询(在排序或筛选运算符移除或重新排列了索引后)。

  • 包含 Take、TakeWhile、Skip、SkipWhile 运算符并且源序列中的索引未采用原始顺序的查询。

  • 包含 Zip 或 SequenceEquals 的查询,除非其中一个数据源具有按原始顺序排列的索引,并且另一个数据源可建立索引 (例如:数组 或 IList(T)).

  • 包含 Concat 的查询,除非将其应用到可建立索引的数据源。

  • 包含 Reverse 的查询,除非应用到可建立索引的数据源。

6) 强制PLINQ并行查询

我们可以通过 WithExecutionMode<TSource> 运算符,指定 ParallelExecutionMode.ForceParallelism  强制PLINQ并行查询。

7)ForAll 多线程枚举

你有可能对“多线程枚举”这个词感到莫名其妙,先看图:

如果你用 foreach、即 IEnumerable 接口枚举并行查询结果,其流程图如第一个所示:即多个线程并行完成后,

还会有一个Merger操作,使结果回到使用该数据的主线程、并将数据合并。

而 ForAll是并行版本的Foreach.

8)其他运算符

1、AsOrdered<TSource>  PLINQ查询默认是不保留顺序的。该运算符可保留源序列的顺序(会产生额外的排序开销、降低性能)。

2、AsUnordered<TSource>  是 AsOrdered<TSource>的反操作、对后续操作不在保持序列,可用于中间查询、提高性能。

  AsUnordered can be called anywhere in the query; it does not need to be called immediately after AsParallel.

3、WithCancellation<TSource> 用于取消操作

4、WithDegreeOfParallelism<TSource>   用以指定最大可使用的处理器数量。

9)补充:影响PLINQ查询性能的因素

附,Demo : http://files.cnblogs.com/files/08shiyan/ParallelDemo.zip

.NET 实现并行的几种方式(三)相关推荐

  1. .NET 实现并行的几种方式(二)

    本随笔续接:.NET 实现并行的几种方式(一) 四.Task 3)Task.NET 4.5 中的简易方式 在上篇随笔中,两个Demo使用的是 .NET 4.0 中的方式,代码写起来略显麻烦,这不 .N ...

  2. java并行任务,Java 并发编程学习(五):批量并行执行任务的两种方式

    Java 并发编程学习(五):批量并行执行任务的两种方式 背景介绍 有时候我们需要执行一批相似的任务,并且要求这些任务能够并行执行.通常,我们的需求会分为两种情况: 并行执行一批任务,等待耗时最长的任 ...

  3. .NET 实现并行的几种方式(一)

    好久没有更新了,今天来一篇,算是<同步与异步>系列的开篇吧,加油,坚持下去(PS:越来越懒了). 一.Thread 利用Thread 可以直接创建和控制线程,在我的认知里它是最古老的技术了 ...

  4. SpringBoot静态获取 bean的三种方式,你学会了吗?

    欢迎关注方志朋的博客,回复"666"获面试宝典 来源:blog.csdn.net/showchi/article/details/97005720 注意:调用者要被spring管理 ...

  5. C++ 遍历set的三种方式

    C++ 遍历set的三种方式 三种方式 set<int> s = mm[ques];             for (auto it = s.cbegin(); it != s.cend ...

  6. Spring Boot 获取 Bean 的 3 种方式!还有谁不会?

    作者 | chilx 来源 | https://blog.csdn.net/showchi/article/details/97005720 注意:调用者要被spring管理 方式一 注解@PostC ...

  7. java创建对象的五种方式

    java创建对象的五种方式 一.使用new关键字 二.使用clone方法 三.使用反序列化 四.使用反射 五.使用Unsafe 一.使用new关键字 如 User user=new User(); 执 ...

  8. Android获取屏幕信息的几种方式

    方式一 //获取屏幕信息的几种方式一:DisplayMetrics metrics = new DisplayMetrics();WindowManager manager = (WindowMana ...

  9. MySQL启动与关闭的3种方式

    MySQL启动与关闭的3种方式 在这里大概记述一下MySQL最常用的3种启动与关闭的方式 文章目录 MySQL启动与关闭的3种方式 一.第一种方式 二.第二种方式 三.第三种方式 总结 一.第一种方式 ...

最新文章

  1. 阿里再次主办大数据世界杯, KDD Cup2020正式开赛
  2. String.fromCharCode()
  3. python学习-练习题兔子生长问题巩固
  4. How to remove replication in SyteLine V2
  5. 良心推荐:高品质音乐播放器Audirvana for Mac
  6. 马的走法编程java_马周游问题(Java实现)
  7. mvc 在视图中调用别的视图
  8. 避免jQuery名字冲突--noConflict()方法
  9. 【Silverlight】Bing Maps学习系列(八):使用Bing Maps Silverlight Control加载自己部署的Google Maps...
  10. CTP接口封装相关贴---集合
  11. 697小说源码PC端+手机端+采集工具(源码带3000本小说的数据)
  12. 基于K—近邻的车牌号识别小实验
  13. [走过的路]联想时光——人艰不拆(店员篇+推销员篇)
  14. 55ide游戏引擎(原赤兔引擎)教程1:认识引擎
  15. 案例实践:用SPSS做K均值聚类分析
  16. 省市区三级联动(带经纬度、离线地图)
  17. Qt5 QML TreeView currentIndex当前选中项的一些问题
  18. 微信小程序单页开发之 min-cli
  19. java des 中文乱码_网络上DesUtil.java关于汉字加密解密出现乱码的问题
  20. mysq学习课堂笔记 第一天学习(值得收藏!)

热门文章

  1. HDU 1176 免费馅饼 (动态规划、另类数塔)
  2. cenos6.4安装gvim
  3. C#链接mysql 新手容易出错的问题
  4. C#在dataGridView中遍历,寻找相同的数据并定位
  5. 监听APP升级广播处理
  6. [hackinglab][CTF][解密关][2020] hackinglab 解密关 writeup
  7. [Bugku][Web][CTF] 9-15 write up
  8. matlab如何找出最小的数据,读取数据并找出全部数据的最大值和最小值
  9. 康宁玻璃ct值计算公式_【钦州】CT室铅板生产厂家
  10. OpenCv学习笔记(二)—cv Mat学习