转载 精进不休 .NET 4.0 (5) - C# 4.0 新特性之并行运算(Parallel) https://www.cnblogs.com/webabcd/archive/2010/06/03/1750449.html
介绍
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
OK
[源码下载]
转载 精进不休 .NET 4.0 (5) - C# 4.0 新特性之并行运算(Parallel) https://www.cnblogs.com/webabcd/archive/2010/06/03/1750449.html的更多相关文章
- C# 4.0 新特性之并行运算(Parallel)
介绍C# 4.0 的新特性之并行运算 Parallel.For - for 循环的并行运算 Parallel.ForEach - foreach 循环的并行运算 Parallel.Invoke - 并 ...
- 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 ...
- Atitit opencv3.0 3.1 3.2 新特性attilax总结
Atitit opencv3.0 3.1 3.2 新特性attilax总结 1. 3.0OpenCV 3 的改动在哪?1 1.1. 模块构成该看哪些模块?2 2. 3.1新特性 2015-12-21 ...
- ArcGIS API for JavaScript 4.2学习笔记[0] AJS4.2概述、新特性、未来产品线计划与AJS笔记目录
放着好好的成熟的AJS 3.19不学,为什么要去碰乳臭未干的AJS 4.2? 4.2全线基础学习请点击[直达] 4.3及更高版本的补充学习请关注我的博客. ArcGIS API for JavaScr ...
- Python 3.8.0 正式版发布,新特性初体验 全面介绍
Python 3.8.0 正式版发布,新特性初体验 北京时间 10 月 15 日,Python 官方发布了 3.8.0 正式版,该版本较 3.7 版本再次带来了多个非常实用的新特性. 赋值表达式 PE ...
- 【译】.NET 5. 0 中 Windows Form 的新特性
自从 Windows Form 在 2018 年底开源并移植到 .NET Core 以来,团队和我们的外部贡献者都在忙于修复旧的漏洞和添加新功能.在这篇文章中,我们将讨论 .NET 5.0 中 Win ...
- C# 8.0的三个令人兴奋的新特性
C# 语言是在2000发布的,至今已正式发布了7个版本,每个版本都包含了许多令人兴奋的新特性和功能更新.同时,C# 每个版本的发布都与同时期的 Visual Studio 以及 .NET 运行时版本高 ...
- Elasticsearch 7.0 发布都有哪些新特性
了解about云知识星球 .pcb{margin-right:0} 问题导读 1.Elasticsearch&Kibana 7.哪些需要修改? 2.Elasticsearch7 有哪些新特性? ...
- Python 3.8.0 正式版发布,新特性初体验
北京时间 10 月 15 日,Python 官方发布了 3.8.0 正式版,该版本较 3.7 版本再次带来了多个非常实用的新特性. 赋值表达式 PEP 572: Assignment Expressi ...
随机推荐
- 【手记】解决涉及office的程序报“Unable to cast COM object of type System._ComObject...”的问题
报错内容大概像这种: 如果该电脑曾经装过WPS,那解决方法就是把WPS装回来,可以不用,但别卸,把它供着,惹不起.
- 将不确定变为确定~老赵写的CodeTimer是代码性能测试的利器
首先,非常感谢赵老大的CodeTimer,它让我们更好的了解到代码执行的性能,从而可以让我们从性能的角度来考虑问题,有些东西可能我们认为是这样的,但经理测试并非如何,这正应了我之前的那名话:“机器最能 ...
- 菜鸟入门【ASP.NET Core】9:RoutingMiddleware介绍以及MVC引入
前言 前面介绍了使用app.Map来配置路由,但是对于一般不是特别大的项目来说,不使用Map来进行路由配置. 配置路由 我们首先需要在Startup.cs文件中的ConfigureServices方法 ...
- 大数据之 Spark
1 渊源 于2009由Matei Zaharia创立了spark大数据处理和计算框架,基于内存,用scala编写. 2 部署 2.1 需要软件包 下载路径见已有博文 Jdk ——因为运行环境为jvm ...
- 【读书笔记】iOS-手势识别
一,事件处理机制 事件是当用户手指触及屏幕,或地屏幕上滑动,或摇晃设备等时候,系统不断地把这些事件通过消息发送给应用程序对象.在iOS设备中能够捕获的事件有3种:触摸事件,移动事件和多媒体远程控制事件 ...
- Tomcat 部署外部系统
/usr/local/tomcat/conf/Catalina/localhost/resource.xml <?xml version='1.0' encoding='utf-8' ?> ...
- 安卓开发_WebView如何在Fragment中使用
之前学习了如何在activity中使用WebView控件来显示网页. 在我的实际开发中,有需要在Fragment中用到WebView控件的,那么就百度学习了一下 其实很简单,但是当然不是和在Activ ...
- debian图形界面安装安装GNOME中文桌面环境_刀光剑影_新浪博客 - Google Chrome
debian图形界面安装安装GNOME中文桌面环境 (2012-06-12 16:47:41) 转载▼ 标签: 杂谈 分类: linux 安装GNOME中文桌面环境 安装基本的X系统 # apt-g ...
- SQL Server的一个不显眼的功能 备份文件的分割
SQL Server的一个不显眼的功能 备份文件的分割 当完整备份数据库的时候,我们有时候可能会遇到一种极端情况,比如服务器上C,D,E三个盘符都只剩下5G空间了 但是如果要完整备份业务库需要12G的 ...
- CENTOS7 SYSTEMD SERVICE 将自己的程序放入自动启动的系统服务
1. 进入文件夹cd /usr/lib/systemd/system 2. 创建文件somed.service 3. 输入内容.如果是监控类程序,需要输入Type=forking[Unit]Descr ...