介绍
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

Parallel的更多相关文章

  1. .Net多线程编程—System.Threading.Tasks.Parallel

    System.Threading.Tasks.Parallel类提供了Parallel.Invoke,Parallel.For,Parallel.ForEach这三个静态方法. 1 Parallel. ...

  2. Java 8函数编程轻松入门(五)并行化(parallel)

    1.并发与并行的区别 并发: 一个时间段内有几个程序都处于已启动到运行完毕之间,且这几个程序都是在同一个处理机上运行.但在任一个时刻点只有一个程序在处理机上运行 并行: 在同一个时刻,多核处理多个任务 ...

  3. Parallel并行之乱用

    关于Parallel我也不细说了,一则微软封装的很好用,二来介绍这个的遍地都是. 我要说的是,要想成为一个优秀的标题党,一定要把重点放到别的地方,为了节省大家阅读时间,我先把结论说了,然后再慢慢从头说 ...

  4. 代码的坏味道(12)——平行继承体系(Parallel Inheritance Hierarchies)

    坏味道--平行继承体系(Parallel Inheritance Hierarchies) 平行继承体系(Parallel Inheritance Hierarchies) 其实是 霰弹式修改(Sho ...

  5. 多线程之任务: Task 基础, 多任务并行执行, 并行运算(Parallel)

    Task - 基于线程池的任务(在 System.Threading.Tasks 命名空间下) 多 Task 的并行执行 Parallel - 并行计算(在 System.Threading.Task ...

  6. Parallel.Foreach

    随着多核时代的到来,并行开发越来越展示出它的强大威力! 使用并行程序,充分的利用系统资源,提高程序的性能.在.net 4.0中,微软给我们提供了一个新的命名空间:System.Threading.Ta ...

  7. 在Parallel中使用DbSet.Add()发现的一系列多线程问题和解决过程

    发现问题 需求很简单,大致就是要批量往数据库写数据,于是打算用Parallel并行的方式写入,希望能利用计算机多核特性加快程序执行速度.想的很美好,于是快速撸了类似下面的一串代码: using (va ...

  8. Intel.parallel.studio.xe.2015.Update.2.ISO-TBE 下载

    磁力链下载点我 还有linux版本 Intel.parallel.studio.xe.2015.Update.1.LINUX.ISO-TBE 收集自网络,要跨请跨原作者,谢谢.

  9. Parallel并行编程初步

    Parallel并行编程可以让我们使用极致的使用CPU.并行编程与多线程编程不同,多线程编程无论怎样开启线程,也是在同一个CPU上切换时间片.而并行编程则是多CPU核心同时工作.耗时的CPU计算操作选 ...

  10. C#~异步编程再续~大叔所理解的并行编程(Task&Parallel)

    返回目录 并行这个概念出自.net4.5,它被封装在System.Threading.Tasks命名空间里,主要提供一些线程,异步的方法,或者说它是对之前Thread进行的二次封装,为的是让开发人员更 ...

随机推荐

  1. 【IdentityServer4文档】- 支持和咨询选项

    支持和咨询选项 我们为 IdentityServer 提供多个免费和商业支持及咨询选项. 免费支持 免费支持是基于社区的,而且使用的是公共论坛 StackOverflow 有越来越多的使用 Ident ...

  2. iOS开发本地通知

    /* 本地通知:不通过网络,在本地实现的通知,自己发给自己 远程通知:必须通过网络,使用推送技术(APNs),实现通知 本地通知: 1.要完成可以接收的通知形式的注册 2.具体通知的设置 3.发送通知 ...

  3. noauth authentication required redis

    解决方案: 这是出现了认证的问题,是因为设置了认证密码. 127.0.0.1:6379> auth "yourpassword" 例如:

  4. pycharm开启代码智能提示和报错提示

    天呐,经历了一大波周折,终于把提示给弄好了,加入没有提示的话,pycharm就是一个空格了,没有什么作用,对我来说,真的是很困难的事情,所以无论如何都要去把这个智能提示给搞好了. 先讲讲我的经历吧.我 ...

  5. STL--heap概述:make_heap,sort_heap,pop_heap,push_heap

    heap并不属于STL容器组件,它分为 max heap 和min heap,在缺省情况下,max-heap是优先队列(priority queue)的底层实现机制. 而这个实现机制中的max-hea ...

  6. 【Docker 命令】- ps命令

    docker ps : 列出容器 语法 docker ps [OPTIONS] OPTIONS说明: -a:显示所有的容器,包括未运行的. -f:根据条件过滤显示的内容. --format :指定返回 ...

  7. phpcms 模型

  8. Delphi中Sender对象的知识

    Sender是一个TObject类型的参数,它告诉Delphi哪个控件接收这个事件并调用相应的处理过程.你可以编写一个单一的事件处理句柄,通过Sender参数和IF…THEN…语句或者CASE语句配合 ...

  9. SSE:服务器发送事件,使用长链接进行通讯 基础学习

    HTML5中新加了EventSounce对象,实现即时推送功能,可以从下面连接中学习, http://www.kwstu.com/ArticleView/kwstu_20140829064746093 ...

  10. 禁止移动端input弹出软键盘

    在做三级联动,或者一些时间插件的时候总是弹出软键盘,用下面的方法就可以禁用掉,废话不多说直接上代码. HTML代码 <div class=""> <div> ...