介绍
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)的更多相关文章

  1. 转载 精进不休 .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 ...

  2. C#5.0新特性

    C#5.0新特性 C#5.0最大的新特性,莫过于Async和Parallel. 以往我们为了让用户界面保持相应,我们可以直接使用异步委托或是System.Threading命名空间中的成员,但Syst ...

  3. 跨时代的MySQL8.0新特性解读

    目录 MySQL发展历程 MySQL8.0新特性 秒级加列 性能提升 文档数据库 SQL增强 共用表表达式(CTEs) 不可见索引(Invisible Indexes) 降序索引(Descending ...

  4. 浅谈Tuple之C#4.0新特性那些事儿你还记得多少?

    来源:微信公众号CodeL 今天给大家分享的内容基于前几天收到的一条留言信息,留言内容是这样的: 看了这位网友的留言相信有不少刚接触开发的童鞋们也会有同样的困惑,除了用新建类作为桥梁之外还有什么好的办 ...

  5. Java基础和JDK5.0新特性

    Java基础 JDK5.0新特性 PS: JDK:Java Development KitsJRE: Java Runtime EvironmentJRE = JVM + ClassLibary JV ...

  6. Visual Studio 2015速递(1)——C#6.0新特性怎么用

    系列文章 Visual Studio 2015速递(1)——C#6.0新特性怎么用 Visual Studio 2015速递(2)——提升效率和质量(VS2015核心竞争力) Visual Studi ...

  7. 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 ...

  8. 背水一战 Windows 10 (1) - C# 6.0 新特性

    [源码下载] 背水一战 Windows 10 (1) - C# 6.0 新特性 作者:webabcd 介绍背水一战 Windows 10 之 C# 6.0 新特性 介绍 C# 6.0 的新特性 示例1 ...

  9. C# 7.0 新特性2: 本地方法

    本文参考Roslyn项目中的Issue:#259. 1. C# 7.0 新特性1: 基于Tuple的“多”返回值方法 2. C# 7.0 新特性2: 本地方法 3. C# 7.0 新特性3: 模式匹配 ...

随机推荐

  1. 第十六篇、MBprogressHUD的使用和获取当前的控制器

    简介: 在开发应用的时候,为了更好的增加用户的体验,常常在客户端向服务端请求数据的时候,在适当的地方加上非模态HUD,让用户可以可以知道当前的进度,稍作等待. MBProgressHUD 第三方框架G ...

  2. IOS- 最简单的反向传值- block

    block 常用于反向传值 声明 返回值类型 (^block)(参数列表) 调用 闭包的名字=^(参数列表){}: 闭包的名字(): 如: void(^aaaaa)(int num,NSString ...

  3. C++ 二维数组(双重指针作为函数参数)

    本文的学习内容参考:http://blog.csdn.net/yunyun1886358/article/details/5659851 http://blog.csdn.net/xudongdong ...

  4. C++重写与重载、重定义

    文章引用自:http://blog.163.com/clevertanglei900@126/blog/static/111352259201102441934870/ 重载overload:是函数名 ...

  5. springmvc学习(一)helloworld实例

    今天介绍的是springmvc的学习,越来越多的企业开始选择springmvc+mybatis来构建系统架构,在电商热门的今天,springmvc+mybatis已成为电商项目架构的很好搭配.Spri ...

  6. 九度OJ 1385 重建二叉树

    题目地址:http://ac.jobdu.com/problem.php?pid=1385 题目描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都 ...

  7. Windows Phone 动态改变ListBox样式

    使用ListBox时通常会借助ItemTemplate帮助我们实现更复杂多样的样式显示,体现了Xaml的灵活.如何动态改变变ListBox的样式,实现类似电脑资源管理器中列表显示和图标显示形式的替换. ...

  8. python 自动化之路 day 04

    内容目录: 1. 函数基本语法及特性 2. 参数与局部变量 3. 返回值 4.嵌套函数 5.递归 6.匿名函数 7.函数式编程介绍 8.高阶函数 9.内置函数 1.函数基本语法及特性 背景提要 现在老 ...

  9. leetcode Insert Interval 区间插入

    作者:jostree  转载请注明出处 http://www.cnblogs.com/jostree/p/4051169.html 题目链接:leetcode Insert Interval 使用模拟 ...

  10. Qwt的编译与配置

    QWT,全称是Qt Widgets for Technical Applications,是一个基于LGPL版权协议的开源项目, 可生成各种统计图.它为具有技术专业背景的程序提供GUI组件和一组实用类 ...