多核时代 .NET Framework 4 中的并行编程5---并行循环Parallel Loop

简介:

1. 并行循环与顺序循环区别

首先,来运行下面的代码,查看区别,代码如下:

static void Main(string[] args)

        {

            Console.WriteLine("使用For循环");

 

            for (int i = 0; i <= 10; i++)

            {

                Console.WriteLine("i = {0}, 线程id = {1}",

                    i, Thread.CurrentThread.ManagedThreadId);

                Thread.Sleep(10);

            }

 

            Console.WriteLine("使用Parallel.For");

 

            Parallel.For(0, 10, i =>

            {

                Console.WriteLine("i = {0}, 线程id = {1}", i,

                Thread.CurrentThread.ManagedThreadId);

                Thread.Sleep(10);

            });

 

            Console.ReadLine();

        }

最终运行的效果如下图所示:

 

从上面的代码运行效果图来我们可以看到,只有一个线程在处理for循环.而Parallel.For的循环,则会有多个线程进行处理,从而在某种程度改善了程序代码的运行效率.他们的区别就不言而喻.

2. Parallel的并行循环的几种方法

Parallel类提供以下几种并行执行循环的方法(他们还有很多其他的重载方法)。具体说明如下:

Ø Parallel.For:执行 for 循环,其中可能会并行运行迭代.

Ø Parallel.ForEach: 对某种集合中的对象执行 foreach,其中可能会并行运行迭代,需要主要的是,它不保证按照集合的索引顺序去执行迭代。

Ø Parallel.Invoke:尽可能并行执行提供的每个操作.

示例代码如下:

private static void Invoke()

        {

            Action[] actions = new Action[5];

            actions[0] = new Action(() =>

             {

                 Console.WriteLine("thread id={0}",Thread.CurrentThread.ManagedThreadId);

             });

            actions[1] = new Action(() =>

            {

                Console.WriteLine("thread id={0}",Thread.CurrentThread.ManagedThreadId);

            });

            actions[2] = new Action(() =>

            {

                Console.WriteLine("thread id={0}",Thread.CurrentThread.ManagedThreadId);

            });

            actions[3] = new Action(() =>

            {

                Console.WriteLine("thread id={0}",Thread.CurrentThread.ManagedThreadId);

            });

            actions[4] = new Action(() =>

            {

                Console.WriteLine("thread id={0}",Thread.CurrentThread.ManagedThreadId);

            });

 

            Parallel.Invoke(actions);

          

 

            List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6 };

 

            Parallel.ForEach(list, i =>

            {

                Console.WriteLine("i={0},thread id={1}", i,Thread.CurrentThread.ManagedThreadId);

            });

 

            Console.ReadLine();

        }

3. 返回值

ParallelLoopResult提供执行 Parallel 循环的完成状态。其中, ParallelLoopResult有两个属性:

Ø IsCompleted 获取该循环是否已运行完成(即,该循环的所有迭代均已执行,并且该循环没有收到提前结束的请求)。 

Ø LowestBreakIteration 获取从中调用 Break 的最低迭代的索引。

代码如下:

ParallelLoopResult loopResult = Parallel.ForEach(list, (int i,ParallelLoopState state) =>

             {

                 if (i == 5)

                 {

                     state.Break();

                 }

                 Console.WriteLine("i={0},thread id={1}", i,Thread.CurrentThread.ManagedThreadId);

             });

 

            Console.WriteLine("IsCompleted: {0}", loopResult.IsCompleted);

            Console.WriteLine("BreakValue: {0}", loopResult.LowestBreakIteration.HasValue);

            Console.ReadLine();

 

4. 控制循环

ParallelOptions类存储用于配置 Parallel 类的方法的操作的选项。其属性有:

Ø CancellationToken 获取或设置与此 ParallelOptions 实例关联的 CancellationToken。 

Ø MaxDegreeOfParallelism 获取或设置此 ParallelOptions 实例所允许的最大并行度。 

Ø TaskScheduler 获取或设置与此 ParallelOptions 实例关联的 TaskScheduler。 将此属性设置为 null,以指示应使用当前计划程序。

如下代码,通过设置CancellationToken以便可以取消Parallel的循环:

CancellationTokenSource token = new CancellationTokenSource();

            Task.Factory.StartNew(() =>

            {

                Thread.Sleep(5000);

                token.Cancel();

                Console.WriteLine("Token Cancelled.");

 

            });

            ParallelOptions loopOptions = new ParallelOptions()

            {

                CancellationToken = token.Token,

                MaxDegreeOfParallelism = 2

 

            };

            try

            {

               

                Parallel.For(0, Int64.MaxValue, loopOptions, i =>

                {

                  

                    Console.WriteLine("i={0},thread id={1}", i,Thread.CurrentThread.ManagedThreadId);

                    Thread.Sleep(1000);

                });

            }

            catch (OperationCanceledException)

            {

                Console.WriteLine("Exception...");

            }

其中, MaxDegreeOfParallelism设置为2,表示最多可以有2个并行量(可以理解成并行线程数目),如果设置为为 -1,表示对于应该使用的并行量没有上限设置。如果将其设置为1,则效果和单线程一样.

5. 停止/中断循环

通过调用ParallelLoopState实例的Stop方法和Break方法,可以停止和中断当前循环的执行.其中,

Ø Break 告知 Parallel 循环应在系统方便的时候尽早停止执行当前迭代之外的迭代.

Ø Stop 告知 Parallel 循环应在系统方便的时候尽早停止执行。

代码如下:

 Parallel.ForEach(list, (int i, ParallelLoopState state) =>

            {

                if (i == 5)

                {

                    state.Break();

                }

               

                Console.WriteLine("i={0},thread id={1}", i,Thread.CurrentThread.ManagedThreadId);

            });

其中, ParallelLoopState类的实例由Parallel类自动创建并传递到所执行的方法中.所以我们可以直接使用,而不是需要事前申明并实例一个ParallelLoopState对象.



    本文转自风车车  博客园博客,原文链接:http://www.cnblogs.com/xray2005/archive/2011/08/30/2159052.html,如需转载请自行联系原作者




相关文章
|
7月前
|
关系型数据库 MySQL 数据库
找不到请求的 .Net Framework Data Provider。可能没有安装
做的一个项目,框架为.net framework 数据库为mysql 出现如标题错误 检查是否安装mysql、是否安装mysql connector net 笔者是因为没有安装后者mysql connector net 下载地址: [mysql connector net](https://downloads.mysql.com/archives/c-net/ "mysql connector net") 笔者安装截图如下: ![请在此添加图片描述](https://developer-private-1258344699.cos.ap-guangzhou.myqcloud.com/c
71 0
|
5天前
|
开发框架 .NET C#
探索VB.NET:了解.NET Framework下的Visual Basic
【4月更文挑战第27天】Visual Basic进化为VB.NET,融入.NET Framework,提供面向对象编程、泛型、LINQ等特性。VB.NET是强类型语言,支持类型推断,通过Windows Forms和WPF构建桌面应用。广泛应用于企业级、Web和数据处理开发,是易学且功能强大的编程工具。随着.NET版本更新,VB.NET的应用仍具价值,适合初学者和资深开发者。
|
2月前
|
Windows
windows server 2019 安装NET Framework 3.5失败,提示:“安装一个或多个角色、角色服务或功能失败” 解决方案
windows server 2019 安装NET Framework 3.5失败,提示:“安装一个或多个角色、角色服务或功能失败” 解决方案
172 0
|
5月前
|
C# Windows
C#安装“Windows 窗体应用(.NET Framework)”
C#安装“Windows 窗体应用(.NET Framework)”
53 0
|
4月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
45 0
|
7天前
|
开发框架 前端开发 JavaScript
JavaScript云LIS系统源码ASP.NET CORE 3.1 MVC + SQLserver + Redis医院实验室信息系统源码 医院云LIS系统源码
实验室信息系统(Laboratory Information System,缩写LIS)是一类用来处理实验室过程信息的软件,云LIS系统围绕临床,云LIS系统将与云HIS系统建立起高度的业务整合,以体现“以病人为中心”的设计理念,优化就诊流程,方便患者就医。
16 0
|
2月前
|
开发框架 前端开发 .NET
进入ASP .net mvc的世界
进入ASP .net mvc的世界
32 0
|
2月前
mvc.net分页查询案例——mvc-paper.css
mvc.net分页查询案例——mvc-paper.css
5 0
|
2月前
|
开发框架 前端开发 .NET
C# .NET面试系列六:ASP.NET MVC
<h2>ASP.NET MVC #### 1. MVC 中的 TempData\ViewBag\ViewData 区别? 在ASP.NET MVC中,TempData、ViewBag 和 ViewData 都是用于在控制器和视图之间传递数据的机制,但它们有一些区别。 <b>TempData:</b> 1、生命周期 ```c# TempData 的生命周期是短暂的,数据只在当前请求和下一次请求之间有效。一旦数据被读取,它就会被标记为已读,下一次请求时就会被清除。 ``` 2、用途 ```c# 主要用于在两个动作之间传递数据,例如在一个动作中设置 TempData,然后在重定向到另
101 5
|
4月前
|
XML 前端开发 定位技术
C#(NET Core3.1 MVC)生成站点地图(sitemap.xml)
C#(NET Core3.1 MVC)生成站点地图(sitemap.xml)
27 0