新的一年,也想通了很多事情,放下了看开了,仅仅是她的一句话,引发了我无尽的思考,回首往事,我现
在能更自信,更坚强的面对我的未来...
C# 4.0 的新特性之并行运算
1. Parallel.For - for 循环的并行运算
2. Parallel.ForEach - foreach 循环的并行运算
3. Parallel.Invoke - 并行调用多个任务
4. Task - 任务,基于线程池。其使我们对并行编程变得更简单,且不用关心底层是怎么实现的
5. PLINQ - 用于对内存中的数据做并行运算,也就是说其只支持 LINQ to Object 的并行运算
1,2 Parallel也是.net 4中最重要更新之一,这也是预示未来的计算趋势,也与网格计算,框计算,甚至是云计算
等等有异曲同工之妙
private static List<int> list = new List<int>();
static void Main(string[] args)
{
InitData();
Normal();
ParallelFor(); // 1 parallel.for
ParallelForeach(); // 2 parallel.foreach
}
private static void InitData()
{
list.Clear();
for (int i = 0; i < 20; i++)
{
list.Add(i);
}
}
private static void Normal()
{
DateTime dt = DateTime.Now;
Console.WriteLine("普通循环");
for (int i = 0; i < 20; i++)
{
GetData(i);
}
Console.WriteLine("消耗时间为:" + (DateTime.Now - dt).TotalSeconds + "秒");
Console.WriteLine();
}
private static void ParallelFor()
{
DateTime dt = DateTime.Now;
Console.WriteLine("并行for");
System.Threading.Tasks.Parallel.For(0, 20, (i) => { GetData(i); });
Console.WriteLine("消耗时间为:" + (DateTime.Now - dt).TotalSeconds + "秒");
Console.WriteLine();
}
private static void ParallelForeach()
{
DateTime dt = DateTime.Now;
Console.WriteLine("并行foreach");
System.Threading.Tasks.Parallel.ForEach(list, (i) => { GetData(i); });
Console.WriteLine("消耗时间为:" + (DateTime.Now - dt).TotalSeconds + "秒");
Console.WriteLine();
}
static int GetData(int i)
{
System.Threading.Thread.Sleep(100);
Console.Write(i.ToString()+"\t");
return i;
}
![Dot Net FrameWork 4.0 学习笔记(5) - 無牽℡↘嘸褂 - 菁华隐没℡↘芳流歇绝 Dot Net FrameWork 4.0 学习笔记(5) - 無牽℡↘嘸褂 - 菁华隐没℡↘芳流歇绝](http://img.bimg.126.net/photo/t-CA4uazqvL4SaCtrq5b7w==/4540754324313091682.jpg)
3. parallel.Invoke 并行调用,在同一瞬间利用处理器的多线程机制,同时触发执行每个操作,
当然在这之前,你首先要保证你的每个操作具备原子性特点.(若操作之间有并发数据问题)
var tasks = new Action[] { () => Task1(), () => Task2(), () => Task3() };
// System.Threading.Tasks.Parallel.Invoke - 并行调用多个任务
System.Threading.Tasks.Parallel.Invoke(tasks);
![Dot Net FrameWork 4.0 学习笔记(5) - 無牽℡↘嘸褂 - 菁华隐没℡↘芳流歇绝 Dot Net FrameWork 4.0 学习笔记(5) - 無牽℡↘嘸褂 - 菁华隐没℡↘芳流歇绝](http://img.bimg.126.net/photo/vLNwD1QIKVqAEjIuSuQ48Q==/4540754324313091683.jpg)
4. Task
/*
* CancellationTokenSource - 取消任务的操作需要用到的一个类
* Token - 一个 CancellationToken 类型的对象,用于通知取消指定的操作
* IsCancellationRequested - 是否收到了取消操作的请求
* Cancel() - 结束任务的执行
* ParallelOptions - 并行运算选项
* CancellationToken - 设置一个 Token,用于取消任务时的相关操作
* MaxDegreeOfParallelism - 指定一个并行循环最多可以使用多少个线程
*/
CancellationTokenSource cts = new CancellationTokenSource();
ParallelOptions pOption = new ParallelOptions() { CancellationToken = cts.Token };
pOption.MaxDegreeOfParallelism = 10;
Console.WriteLine("开始执行,2.0 秒后结束");
/*
* Task - 任务类
* Factory.StartNew() - 创建并开始一个或一批新任务
* ContinueWith() - 此任务完成后执行指定的另一个任务
* AsyncState - 此任务的上下文对象
* Wait() - 阻塞,直到任务完成
*/
Task task0 = Task.Factory.StartNew(() =>
{
Thread.Sleep(2000);
cts.Cancel();
Console.WriteLine("结束");
});
var tasks = new Action[] { () => Task1(), () => Task2() };
// 利用第三知识点,再传入并行任务操作选项
System.Threading.Tasks.Parallel.Invoke(pOption,tasks);
private static void Task1(CancellationToken token)
{
// 每隔 1 秒执行一次,直到此任务收到了取消的请求
// 注意:虽然此处是其他线程要向主线程(UI线程)上输出信息,但因为使用了 Task ,所以不用做任何处理
while (!token.IsCancellationRequested)
{
Console.WriteLine("Task1 - " + "当前线程ID: " + Thread.CurrentThread.ManagedThreadId.ToString());
Thread.Sleep(1000);
}
}
private static void Task2(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
Console.WriteLine("Task2 - " + "当前线程ID: " + Thread.CurrentThread.ManagedThreadId.ToString());
Thread.Sleep(1000);
}
}
/*
* 一个 Task 内可以包含多个 Task
Task tasks = new Task(() =>
{
Task.Factory.StartNew(() => Method());
Task.Factory.StartNew(() => Method2());
Task.Factory.StartNew(() => Method3());
});
tasks.Start();
// 阻塞,直到整个任务完成
tasks.Wait();
*/
5. PLINQ LINQ to Object的并行计算方式
// 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;
比较强大的linq并行计算方式,甚至用于聚合函数的并行都也是可以的.
list.AsParallel().Average().ToString()
当然一个前提就是以上的并行计算拓展方法肯定是不能用在顺序计算当中的..
![Dot Net FrameWork 4.0 学习笔记(5) - 無牽℡↘嘸褂 - 菁华隐没℡↘芳流歇绝 Dot Net FrameWork 4.0 学习笔记(5) - 無牽℡↘嘸褂 - 菁华隐没℡↘芳流歇绝](http://img.bimg.126.net/photo/jxcEjMY5r0PDOGkbhWRI5g==/5369698130710040524.gif)
下节知识点 ado.net data service(WCF Data Service)