C# 4.0 新特性之并行运算(Parallel)
介绍
C# 4.0 的新特性之并行运算
- Parallel.For - for 循环的并行运算
- Parallel.ForEach - foreach 循环的并行运算
- Parallel.Invoke - 并行调用多个任务
- Task - 任务,基于线程池。其使我们对并行编程变得更简单,且不用关心底层是怎么实现的
- PLINQ - 用于对内存中的数据做并行运算,也就是说其只支持 LINQ to Object 的并行运算
- LIST等泛型启用并行计算很简单,使用AsParallel()即可
示例
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
C# 4.0 新特性之并行运算(Parallel)的更多相关文章
- 转载 精进不休 .NET 4.0 (5) - C# 4.0 新特性之并行运算(Parallel) https://www.cnblogs.com/webabcd/archive/2010/06/03/1750449.html
精进不休 .NET 4.0 (5) - C# 4.0 新特性之并行运算(Parallel) 介绍C# 4.0 的新特性之并行运算 Parallel.For - for 循环的并行运算 Parall ...
- C#5.0新特性
C#5.0新特性 C#5.0最大的新特性,莫过于Async和Parallel. 以往我们为了让用户界面保持相应,我们可以直接使用异步委托或是System.Threading命名空间中的成员,但Syst ...
- 跨时代的MySQL8.0新特性解读
目录 MySQL发展历程 MySQL8.0新特性 秒级加列 性能提升 文档数据库 SQL增强 共用表表达式(CTEs) 不可见索引(Invisible Indexes) 降序索引(Descending ...
- 浅谈Tuple之C#4.0新特性那些事儿你还记得多少?
来源:微信公众号CodeL 今天给大家分享的内容基于前几天收到的一条留言信息,留言内容是这样的: 看了这位网友的留言相信有不少刚接触开发的童鞋们也会有同样的困惑,除了用新建类作为桥梁之外还有什么好的办 ...
- Java基础和JDK5.0新特性
Java基础 JDK5.0新特性 PS: JDK:Java Development KitsJRE: Java Runtime EvironmentJRE = JVM + ClassLibary JV ...
- Visual Studio 2015速递(1)——C#6.0新特性怎么用
系列文章 Visual Studio 2015速递(1)——C#6.0新特性怎么用 Visual Studio 2015速递(2)——提升效率和质量(VS2015核心竞争力) Visual Studi ...
- atitit.Servlet2.5 Servlet 3.0 新特性 jsp2.0 jsp2.1 jsp2.2新特性
atitit.Servlet2.5 Servlet 3.0 新特性 jsp2.0 jsp2.1 jsp2.2新特性 1.1. Servlet和JSP规范版本对应关系:1 1.2. Servlet2 ...
- 背水一战 Windows 10 (1) - C# 6.0 新特性
[源码下载] 背水一战 Windows 10 (1) - C# 6.0 新特性 作者:webabcd 介绍背水一战 Windows 10 之 C# 6.0 新特性 介绍 C# 6.0 的新特性 示例1 ...
- C# 7.0 新特性2: 本地方法
本文参考Roslyn项目中的Issue:#259. 1. C# 7.0 新特性1: 基于Tuple的“多”返回值方法 2. C# 7.0 新特性2: 本地方法 3. C# 7.0 新特性3: 模式匹配 ...
随机推荐
- 查看Unix系统是32位还是64位
#getconf查看OS位数 以下经过测试了HP: getconf KERNEL_BITSLinux: getconf LONG_BITAIX: getconf KERNEL_BITMODE #AIX ...
- 轮子来袭 vJine.Core Orm 之 03_架构分析
1.vJine.Core ORM 架构: 如上图所示,vJine.Core ORM的特点如下: 所有操作均以DataManager为核心: DataManager业务部分的增删改查操作依赖于Class ...
- JS函数的参数对象arguments在严格模式下的限制
在JS中,传入的函数的参数个数可以与定义函数的个数不一致,那么对于传入的实参的引用,则是arguments对象.然而改对象在严格模式和非严格模式下是由区分的: 1 在严格模式下arguments作为了 ...
- zoj 3829 Known Notation
作者:jostree 转载请说明出处 http://www.cnblogs.com/jostree/p/4020792.html 题目链接: zoj 3829 Known Notation 使用贪心+ ...
- 在Mac OS X中使用VIM开发STM32(1)
本文原创于http://www.cnblogs.com/humaoxiao,非法转载者请自重! 在我先前的博文⎣在Mac OS X中搭建STM32开发环境⎤中,我们在Mac中DIY出了最 ...
- Aspose.Words 总结
生成答题卡 try { string tempPath = @"D:\moban\ttt.doc"; //Open document and create Documentbuil ...
- 转.....IOC 和DI
引述:IoC(控制反转:Inverse of Control)是Spring容器的内核,AOP.声明式事务等功能在此基础上开花结果.但是IoC这个重要的概念却比较晦涩隐讳,不容易让人望文生义,这不能不 ...
- WPF MVVM 用户控件完成分页
项目中经常会有分页查询的情况,在WPF中我们可以通过用户控件完成分页 一下为分页控件的页面代码, <UserControl x:Class="Foundation.UCtrl.Next ...
- [HTML] <input> 标签
可选的属性 属性 值 描述 accept mime_type 规定通过文件上传来提交的文件的类型. align left right top middle bottom 不赞成使用.规定图像输入的 ...
- Oracle 事务相关的一些测试
1.sqlplus 客户端正常退出 SQL> desc t; 名称 是否为空? 类型 ----------------------------------------- -------- --- ...