Parallel
介绍
C# 4.0 的新特性之并行运算
- Parallel.For - for 循环的并行运算
- Parallel.ForEach - foreach 循环的并行运算
- Parallel.Invoke - 并行调用多个任务
- Task - 任务,基于线程池。其使我们对并行编程变得更简单,且不用关心底层是怎么实现的
- PLINQ - 用于对内存中的数据做并行运算,也就是说其只支持 LINQ to Object 的并行运算
示例
1、Parallel.For 的 Demo
Parallel/ParallelFor.aspx.cs
代码 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace CSharp.Parallel { public partial class ParallelFor : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { Normal(); ParallelForDemo(); } private void Normal() { DateTime dt = DateTime.Now; for (int i = 0; i < 20; i++) { GetData(i); } Response.Write((DateTime.Now - dt).TotalMilliseconds.ToString()); Response.Write("<br />"); Response.Write("<br />"); } private void ParallelForDemo() { DateTime dt = DateTime.Now; // System.Threading.Tasks.Parallel.For - for 循环的并行运算 System.Threading.Tasks.Parallel.For(0, 20, (i) => { GetData(i); }); Response.Write((DateTime.Now - dt).TotalMilliseconds.ToString()); Response.Write("<br />"); } private int GetData(int i) { System.Threading.Thread.Sleep(100); Response.Write(i.ToString()); Response.Write("<br />"); return i; } } } /* 运行结果: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 2000.0514 0 13 1 19 7 12 18 6 2 8 10 14 4 16 5 3 15 17 9 11 300.0077 */
2、Parallel.ForEach 的 Demo
Parallel/ParallelForEach.aspx.cs
代码 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace CSharp.Parallel { public partial class ParallelForEach : System.Web.UI.Page { private List<int> _data = new List<int>(); protected void Page_Load(object sender, EventArgs e) { InitData(); Normal(); ParallelForEachDemo(); } private void InitData() { _data.Clear(); for (int i = 0; i < 20; i++) { _data.Add(i); } } private void Normal() { DateTime dt = DateTime.Now; for (int i = 0; i < 20; i++) { GetData(i); } Response.Write((DateTime.Now - dt).TotalMilliseconds.ToString()); Response.Write("<br />"); Response.Write("<br />"); } private void ParallelForEachDemo() { DateTime dt = DateTime.Now; // System.Threading.Tasks.Parallel.ForEach - foreach 循环的并行运算 System.Threading.Tasks.Parallel.ForEach(_data, (index) => { GetData(index); }); Response.Write((DateTime.Now - dt).TotalMilliseconds.ToString()); Response.Write("<br />"); } private int GetData(int i) { System.Threading.Thread.Sleep(100); Response.Write(i.ToString()); Response.Write("<br />"); return i; } } } /* 运行结果: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 2000.0514 0 6 12 18 1 2 7 13 19 4 3 8 14 9 5 15 10 16 11 17 600.0154 */
3、Parallel.Invoke 的 Demo
Parallel/ParallelInvoke.aspx.cs
代码 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Threading; namespace CSharp.Parallel { public partial class ParallelInvoke : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { var tasks = new Action[] { () => Task1(), () => Task2(), () => Task3() }; // System.Threading.Tasks.Parallel.Invoke - 并行调用多个任务 System.Threading.Tasks.Parallel.Invoke(tasks); } private void Task1() { Thread.Sleep(3000); Response.Write("Task1 - " + "ThreadId:" + Thread.CurrentThread.ManagedThreadId.ToString() + " - " + DateTime.Now.ToString("HH:mm:ss")); Response.Write("<br />"); } private void Task2() { System.Threading.Thread.Sleep(3000); Response.Write("Task2 - " + "ThreadId:" + Thread.CurrentThread.ManagedThreadId.ToString() + " - " + DateTime.Now.ToString("HH:mm:ss")); Response.Write("<br />"); } private void Task3() { System.Threading.Thread.Sleep(3000); Response.Write("Task3 - " + "ThreadId:" + Thread.CurrentThread.ManagedThreadId.ToString() + " - " + DateTime.Now.ToString("HH:mm:ss")); Response.Write("<br />"); } } } /* 运行结果: Task2 - ThreadId:26 - 09:11:58 Task1 - ThreadId:25 - 09:11:58 Task3 - ThreadId:24 - 09:11:58 */
4、Task 的 Demo
Parallel/ParallelTask.aspx.cs
代码 /* Task - 任务,基于线程池。其使我们对并行编程变得更简单,且不用关心底层是怎么实现的 */ using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Threading; using System.Threading.Tasks; namespace CSharp.Parallel { public partial class ParallelTask : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { /* * CancellationTokenSource - 取消任务的操作需要用到的一个类 * Token - 一个 CancellationToken 类型的对象,用于通知取消指定的操作 * IsCancellationRequested - 是否收到了取消操作的请求 * Cancel() - 结束任务的执行 * ParallelOptions - 并行运算选项 * CancellationToken - 设置一个 Token,用于取消任务时的相关操作 * MaxDegreeOfParallelism - 指定一个并行循环最多可以使用多少个线程 */ CancellationTokenSource cts = new CancellationTokenSource(); ParallelOptions pOption = new ParallelOptions() { CancellationToken = cts.Token }; pOption.MaxDegreeOfParallelism = 10; Response.Write("开始执行,3.5 秒后结束"); Response.Write("<br />"); /* * Task - 任务类 * Factory.StartNew() - 创建并开始一个或一批新任务 * ContinueWith() - 此任务完成后执行指定的另一个任务 * AsyncState - 此任务的上下文对象 * Wait() - 阻塞,直到任务完成 */ Task task0 = Task.Factory.StartNew(() => { Thread.Sleep(3500); cts.Cancel(); Response.Write("结束"); Response.Write("<br />"); }); // 通过 System.Threading.Tasks.Parallel.Invoke 执行任务的时候,可以加入 ParallelOptions 参数,用于对此并行运算做一些配置 System.Threading.Tasks.Parallel.Invoke(pOption, () => Task1(pOption.CancellationToken), () => Task2(pOption.CancellationToken)); /* * 一个 Task 内可以包含多个 Task Task tasks = new Task(() => { Task.Factory.StartNew(() => Method()); Task.Factory.StartNew(() => Method2()); Task.Factory.StartNew(() => Method3()); }); tasks.Start(); // 阻塞,直到整个任务完成 tasks.Wait(); */ /* * 带返回值的 Task Func<object, long> fun = delegate(object state) { return 1.0; }; Task<long> tsk = new Task<long>(fun, "state"); tsk.Start(); Response.Write(tsk.Result.ToString()); */ } private void Task1(CancellationToken token) { // 每隔 1 秒执行一次,直到此任务收到了取消的请求 // 注意:虽然此处是其他线程要向主线程(UI线程)上输出信息,但因为使用了 Task ,所以不用做任何处理 while (!token.IsCancellationRequested) { Response.Write("Task1 - " + "ThreadId: " + Thread.CurrentThread.ManagedThreadId.ToString()); Response.Write("<br />"); Thread.Sleep(1000); } } private void Task2(CancellationToken token) { while (!token.IsCancellationRequested) { Response.Write("Task2 - " + "ThreadId: " + Thread.CurrentThread.ManagedThreadId.ToString()); Response.Write("<br />"); Thread.Sleep(1000); } } } } /* 运行结果: 开始执行,3.5 秒后结束 Task2 - ThreadId: 6 Task1 - ThreadId: 48 Task1 - ThreadId: 48 Task2 - ThreadId: 6 Task2 - ThreadId: 6 Task1 - ThreadId: 48 Task2 - ThreadId: 6 Task1 - ThreadId: 48 结束 */
5、PLINQ 的 Demo
Parallel/ParallelPLINQ.aspx.cs
代码 /* PLINQ - 用于对内存中的数据做并行运算,也就是说其只支持 LINQ to Object 的并行运算 */ using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace CSharp.Parallel { public partial class ParallelPLINQ : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { List<int> list = new List<int>(); for (int i = 0; i < 100; i++) { list.Add(i); } // AsParallel() - 并行运算 // AsSequential() - 串行运算 // AsOrdered() - 保持数据的原有顺序(AsSequential()指的是串行运算;AsOrdered()指的是如果在并行运算的前提下,它会把结果先缓存,然后排序,最后再把排序后的数据做输出) // AsUnordered() - 可以不必保持数据的原有顺序 // WithDegreeOfParallelism() - 明确地指出需要使用多少个线程来完成工作 // WithCancellation(new CancellationTokenSource().Token) - 指定一个 CancellationToken 类型的参数 ParallelQuery nums = from num in list.AsParallel<int>().AsOrdered<int>() where num % 10 == 0 select num; foreach (var num in nums) { Response.Write(num.ToString()); Response.Write("<br />"); } // 聚合方法也可以做并行运算 Response.Write(list.AsParallel().Average().ToString()); Response.Write("<br />"); // 自定义聚合方法做并行运算的 Demo(实现一个取集合的平均值的功能) double myAggregateResult = list.AsParallel().Aggregate( // 聚合变量的初始值 0d, // 在每个数据分区上,计算此分区上的数据 // 第一个参数:对应的数据分区的计算结果;第二个参数:对应的数据分区的每个数据项 (value, item) => { double result = value + item; return result; }, // 根据每个数据分区上的计算结果,再次做计算 // 第一个参数:全部数据的计算结果;第二个参数:每个数据分区上的计算结果 (value, data) => { double result = value + data; return result; }, // 根据全部数据的计算结果再次计算,得到最终的聚合结果 (result) => result / list.Count ); Response.Write(myAggregateResult.ToString()); } } } /* 运行结果: 0 10 20 30 40 50 60 70 80 90 49.5 49.5 */
注:关于并行运算的实例可以参考
http://code.msdn.microsoft.com/ParExtSamples
Parallel的更多相关文章
- .Net多线程编程—System.Threading.Tasks.Parallel
System.Threading.Tasks.Parallel类提供了Parallel.Invoke,Parallel.For,Parallel.ForEach这三个静态方法. 1 Parallel. ...
- Java 8函数编程轻松入门(五)并行化(parallel)
1.并发与并行的区别 并发: 一个时间段内有几个程序都处于已启动到运行完毕之间,且这几个程序都是在同一个处理机上运行.但在任一个时刻点只有一个程序在处理机上运行 并行: 在同一个时刻,多核处理多个任务 ...
- Parallel并行之乱用
关于Parallel我也不细说了,一则微软封装的很好用,二来介绍这个的遍地都是. 我要说的是,要想成为一个优秀的标题党,一定要把重点放到别的地方,为了节省大家阅读时间,我先把结论说了,然后再慢慢从头说 ...
- 代码的坏味道(12)——平行继承体系(Parallel Inheritance Hierarchies)
坏味道--平行继承体系(Parallel Inheritance Hierarchies) 平行继承体系(Parallel Inheritance Hierarchies) 其实是 霰弹式修改(Sho ...
- 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel)
Task - 基于线程池的任务(在 System.Threading.Tasks 命名空间下) 多 Task 的并行执行 Parallel - 并行计算(在 System.Threading.Task ...
- Parallel.Foreach
随着多核时代的到来,并行开发越来越展示出它的强大威力! 使用并行程序,充分的利用系统资源,提高程序的性能.在.net 4.0中,微软给我们提供了一个新的命名空间:System.Threading.Ta ...
- 在Parallel中使用DbSet.Add()发现的一系列多线程问题和解决过程
发现问题 需求很简单,大致就是要批量往数据库写数据,于是打算用Parallel并行的方式写入,希望能利用计算机多核特性加快程序执行速度.想的很美好,于是快速撸了类似下面的一串代码: using (va ...
- Intel.parallel.studio.xe.2015.Update.2.ISO-TBE 下载
磁力链下载点我 还有linux版本 Intel.parallel.studio.xe.2015.Update.1.LINUX.ISO-TBE 收集自网络,要跨请跨原作者,谢谢.
- Parallel并行编程初步
Parallel并行编程可以让我们使用极致的使用CPU.并行编程与多线程编程不同,多线程编程无论怎样开启线程,也是在同一个CPU上切换时间片.而并行编程则是多CPU核心同时工作.耗时的CPU计算操作选 ...
- C#~异步编程再续~大叔所理解的并行编程(Task&Parallel)
返回目录 并行这个概念出自.net4.5,它被封装在System.Threading.Tasks命名空间里,主要提供一些线程,异步的方法,或者说它是对之前Thread进行的二次封装,为的是让开发人员更 ...
随机推荐
- “Hello world!”团队第一周贡献分分配结果
小组名称:Hello World! 项目名称:空天猎 组长:陈建宇 成员:刘成志.阚博文.刘淑霞.黄泽宇.方铭.贾男男 第一周贡献分分配结果 基础分 会议分 提功能分 个人表现分 各项总分 最终分 ...
- 实现虚拟机VMware上Centos的linux与windows互相复制与粘贴
转自:http://blog.csdn.net/u012243115/article/details/40454063 1.打开虚拟机的菜单“虚拟机”,下拉框中会有一个“安装 VMwareTools” ...
- Delegate(QLabel和QComboBox)
一.最终效果 二.实现思路 1.createEditor()中create两个控件,分别是QLabel和QComboBox,将其添加到一个widget中,然后返回该widget: 2.setEdito ...
- android入门 — ListView
ListView主要是用来解决大量数据展示的问题,它的用途很广泛,几乎所有的app都会用到,比如说知乎.今日头条.微博.通讯录等. ListView允许用户通过上下滑动的方式将屏幕外的数据滚动到屏幕中 ...
- mysql入门 — (1)
使用cd进入到mysql/bin文件夹下面,或者配置完环境之后,直接在cmd中使用mysql,然后回车开启mysql. 登录 为了安全考虑,在这里只设置了本地root用户可以连接上数据库.使用的指令是 ...
- LintCode-41.最大子数组
最大子数组 给定一个整数数组,找到一个具有最大和的子数组,返回其最大和. 注意事项 子数组最少包含一个数 样例 给出数组[−2,2,−3,4,−1,2,1,−5,3],符合要求的子数组为[4,−1,2 ...
- 评论模块Demo(XML读写,定时器。)
这个Demo主要是自己做练习熟悉jquery,ajax,与xml文件的读写,以下是实现页面效果: 后台控制器: public ActionResult AddMsg() { XmlDocument x ...
- 第61天:json遍历和封装运动框架(多个属性)
一.json 遍历 for in 关键字 for ( 变量 in 对象) { 执行语句; } 例如: var json = {width:200,height:300,left:50}co ...
- 第29天:js-数组添加删除、数组和字符串相互转换
一.添加数组var arr=[1,3,5];arr.push(7,9);//添加7和9到数组arr后面,得到[1,3,5,7,9]1.push();可向数组末尾添加一个或多个元素,并返回新的长度.2. ...
- RT-thread 设备驱动组件之PIN设备
在RT-thread 2.0.0正式版中引入了pin设备作为杂类设备,其设备驱动文件pin.c在rt-thread-2.0.1\components\drivers\misc中,主要用于操作芯片GPI ...