转载 精进不休 .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 ...
随机推荐
- IdentityServer4 中文文档 -8- (快速入门)设置和概览
IdentityServer4 中文文档 -8- (快速入门)设置和概览 原文:http://docs.identityserver.io/en/release/quickstarts/0_overv ...
- C语言之链表的使用
C语言链表初学者都说很难,今天就来为大家讲讲链表 讲链表之前不得不介绍一下结构体,在链表学习之前大家都应该已经学了结构体,都知道结构体里面能有许多变量,每个变量可以当做这个结构体的属性,例如: str ...
- LINQ分页和排序,skip和Take 用法
LINQ分页和排序,skip和Take 用法 dbconn.BidRecord.OrderBy(p=>p.bid_id).ToList<BidRecord>().OrderBy(p ...
- WPF 使用RPC调用其他进程
如果在 WPF 需要用多进程通信,一个推荐的方法是 WCF ,因为 WCF 是 RPC 计算.先来讲下 RPC (Remote Procedure Call) 远程过程调用,他是通过特定协议,包括 t ...
- angularjs学习第六天笔记(指令简介学习)
您好,由于周末有事情,没哟学习angularjs,几天晚上开始继续学习angularjs,坚持加油每一天.谢谢 接着上周五学习了表单验证以后,今天开始学习angularjs中一个非常重要的模块:指令 ...
- C# 循环语句 for
循环:反复执行某段代码. 循环四要素:初始条件,循环条件,循环体,状态改变. for格式 for(初始条件;循环条件;状态改变) { 循环体 } break ——中断循环,跳出整个循环 continu ...
- 【18】观察者模式(Observer Pattern)
一.引言 在现实生活中,处处可见观察者模式.例如,微信中的订阅号,订阅博客和QQ微博中关注好友,这些都属于观察者模式的应用.在这一章将分享我对观察者模式的理解,废话不多说了,直接进入今天的主题. 二. ...
- 通过jQuery制作电子时钟表的代码
源码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <titl ...
- 正则与python的re模块
一.正则表达式的语法 正则表达式使用反斜杠字符('\')来表示特殊的形式或者来允许使用特殊的字符而不要启用它们特殊的含义.这与字符串字面值中相同目的的相同字符的用法冲突:例如,要匹配一个反斜线字面值, ...
- 2017-10-29 用中文命名API的意义和途径
"中文编程"知乎专栏原链 在前文对在代码中使用中文命名的质疑与回应中阐述了在代码中使用中文命名的益处. 此文将从软件使用者的角度阐述对API中文化的意义并探讨实现途径. 当然, 文 ...