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进行的二次封装,为的是让开发人员更 ...
随机推荐
- 解决python中文编码错误问题
对于初学者而言,编码问题或许还没有没重视起来,但是编码问题是中文开发者必须面对的.今天来看下python开发中如何解决编码问题.注意:本篇讲的是最常见的一种编码问题,其他编码问题,如json函数引起的 ...
- Alpha 冲刺3
队名:日不落战队 安琪(队长) 今天完成的任务 组织第三次站立式会议. 完成了个人信息前端界面. 明天的计划 草稿箱前端界面. 个人信息扩展界面框架. 还剩下的任务 回收站前端界面. 信息修改前端界面 ...
- iOS- 无处不在,详解iOS集成第三方登录(SSO授权登录<无需密码>)
1.前言 不多说,第三登录无处不在!必备技能,今天以新浪微博为例. 这是上次写的iOS第三方社交分享:http://www.cnblogs.com/qingche/p/3727559.html 可 ...
- hadoop2.5.2学习及实践笔记(五)—— HDFS shell命令行常见操作
附:HDFS shell guide文档地址 http://hadoop.apache.org/docs/r2.5.2/hadoop-project-dist/hadoop-common/FileSy ...
- idea dubbo jar error:cvc-complex-type.2.4.c: 通配符的匹配很全面, 但无法找到元素 'dubbo:application' 的声明
声明: 出现这个错误的情形是,在idea开发环境里面运行是没有问题的,使用哦idea自带的打包工具生成jar之后,运行jar的时候报的这个错误,如果不是这个情况,这篇文章可能不适用. 主要的原因是sp ...
- [OS] 多线程--原子操作 Interlocked系列函数
转自:http://blog.csdn.net/morewindows/article/details/7429155 上一篇<多线程--第一次亲密接触 CreateThread与_begint ...
- Nginx + Keepalived使用文档
第一步: 下载keepalived地址:http://www.keepalived.org/download.html 解压安装: tar -zxvf keepalived-1.2.18.tar.gz ...
- 【bzoj1572】[Usaco2009 Open]工作安排Job 贪心+堆
题目描述 Farmer John 有太多的工作要做啊!!!!!!!!为了让农场高效运转,他必须靠他的工作赚钱,每项工作花一个单位时间. 他的工作日从0时刻开始,有1000000000个单位时间(!). ...
- Android Shimmer 发光微光动画
这是Facebook提供的一个类库(题外话http://code.facebook.com,这里有很多好玩有趣有用的Facebook开源的类库) 这么炫酷的发光动画效果,想必很多Android码农都会 ...
- BZOJ2724:[Violet 6]蒲公英——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=2724 输入格式 第一行两个整数n,m,表示有n株蒲公英,m次询问. 接下来一行 n 个空格分隔的整数 ...