精进不休 .NET 4.0 (5) - C# 4.0 新特性之并行运算(Parallel)

简介:
[索引页]
[源码下载]


精进不休 .NET 4.0 (5) - C# 4.0 新特性之并行运算(Parallel)


作者: webabcd


介绍
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 
        { 
void Page_Load() void Page_Load(object sender, EventArgs e) 
                { 
                        Normal(); 
                        ParallelForDemo(); 
                } 

void Normal() 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 />"); 
                } 

void ParallelForDemo() 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 />"); 
                } 

int GetData() int GetData(int i) 
                { 
                        System.Threading.Thread.Sleep(100); 
                        Response.Write(i.ToString()); 
                        Response.Write( "<br />"); 
                        return i; 
                } 
        } 


/* 
运行结果: 










10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
2000.0514 


13 

19 

12 
18 



10 
14 

16 


15 
17 

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 
        { 
List<int> _data =  new List<int>() List<int> _data =  new List<int>(); 

void Page_Load() void Page_Load(object sender, EventArgs e) 
                { 
                        InitData(); 

                        Normal(); 
                        ParallelForEachDemo(); 
                } 

void InitData() void InitData() 
                { 
                        _data.Clear(); 
                         for (int i = 0; i < 20; i++) 
                        { 
                                _data.Add(i); 
                        } 
                } 

void Normal() 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 />"); 
                } 

void ParallelForEachDemo() 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 />"); 
                } 

int GetData() int GetData(int i) 
                { 
                        System.Threading.Thread.Sleep(100); 
                        Response.Write(i.ToString()); 
                        Response.Write( "<br />"); 
                        return i; 
                } 
        } 


/* 
运行结果: 










10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
2000.0514 



12 
18 



13 
19 



14 


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 
        { 
void Page_Load() 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); 
                } 

void Task1() void Task1() 
                { 
                        Thread.Sleep(3000); 
                        Response.Write( "Task1 - " +  "ThreadId:" + Thread.CurrentThread.ManagedThreadId.ToString() +  " - "+ DateTime.Now.ToString( "HH:mm:ss")); 
                        Response.Write( "<br />"); 
                } 

void Task2() void Task2() 
                { 
                        System.Threading.Thread.Sleep(3000); 
                        Response.Write( "Task2 - " +  "ThreadId:" + Thread.CurrentThread.ManagedThreadId.ToString() +  " - "+ DateTime.Now.ToString( "HH:mm:ss")); 
                        Response.Write( "<br />"); 
                } 

void Task3() 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 
        { 
void Page_Load() 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());    
                        */ 
                } 
                
void Task1() void Task1(CancellationToken token) 
                { 
                        // 每隔 1 秒执行一次,直到此任务收到了取消的请求 
                        // 注意:虽然此处是其他线程要向主线程(UI线程)上输出信息,但因为使用了 Task ,所以不用做任何处理 
                         while (!token.IsCancellationRequested) 
                        { 
                                Response.Write( "Task1 - " +  "ThreadId: " + Thread.CurrentThread.ManagedThreadId.ToString()); 
                                Response.Write( "<br />"); 
                                Thread.Sleep(1000); 
                        } 

                } 
void Task2() 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 
        { 
void Page_Load() 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()); 
                }    
        } 


/* 
运行结果: 

10 
20 
30 
40 
50 
60 
70 
80 
90 
49.5 
49.5    
*/
 
 
注:关于并行运算的实例可以参考
http://code.msdn.microsoft.com/ParExtSamples


OK 
[源码下载]





     本文转自webabcd 51CTO博客,原文链接:http://blog.51cto.com/webabcd/341286,如需转载请自行联系原作者

相关文章
|
4月前
|
人工智能 开发框架 .NET
.NET技术的强大功能:.NET技术的基础特性、在现代开发中的应用、以及它如何助力未来的软件开发。
.NET技术是软件开发领域的核心支柱,以其强大功能、灵活性及安全性广受认可。本文分三部分解析:基础特性如多语言支持、统一运行时环境;现代应用如企业级与Web开发、移动应用、云服务及游戏开发;以及未来趋势如性能优化、容器化、AI集成等,展望.NET在不断变化的技术环境中持续发展与创新。
134 4
|
1月前
|
自然语言处理 物联网 图形学
.NET 技术凭借其独特的优势和特性,为开发者们提供了一种高效、可靠且富有创造力的开发体验
本文深入探讨了.NET技术的独特优势及其在多个领域的应用,包括企业级应用、Web应用、桌面应用、移动应用和游戏开发。通过强大的工具集、高效的代码管理、跨平台支持及稳定的性能,.NET为开发者提供了高效、可靠的开发体验,并面对技术更新和竞争压力,不断创新发展。
49 7
|
1月前
|
开发框架 .NET C#
.NET 技术凭借高效开发环境、强大框架支持及跨平台特性,在软件开发中占据重要地位
.NET 技术凭借高效开发环境、强大框架支持及跨平台特性,在软件开发中占据重要地位。从企业应用到电子商务,再到移动开发,.NET 均展现出卓越性能,助力开发者提升效率与项目质量,推动行业持续发展。
29 4
|
2月前
|
JSON C# 开发者
C#语言新特性深度剖析:提升你的.NET开发效率
【10月更文挑战第15天】C#语言凭借其强大的功能和易用性深受开发者喜爱。随着.NET平台的演进,C#不断引入新特性,如C# 7.0的模式匹配和C# 8.0的异步流,显著提升了开发效率和代码可维护性。本文将深入探讨这些新特性,助力开发者在.NET开发中更高效地利用它们。
43 1
|
2月前
|
存储 编译器
.Net特性Attribute的高级使用
【10月更文挑战第14天】在.NET中,特性(Attribute)是一种强大的机制,用于在代码中添加元数据。本文介绍了特性的高级用法,包括自定义特性、通过反射读取特性、条件编译与特性结合、多个特性应用以及特性继承。通过示例展示了如何创建自定义特性类、应用自定义特性,并通过反射获取特性信息。此外,还介绍了如何利用条件编译符号实现不同版本的代码控制,以及如何在一个代码元素上应用多个特性。最后,探讨了如何通过`AttributeUsage`控制特性的继承行为。
|
2月前
|
SQL 传感器 开发框架
今天我们聊聊C#的并发和并行
今天我们聊聊C#的并发和并行
71 1
|
3月前
|
SQL 开发框架 安全
并发集合与任务并行库:C#中的高效编程实践
在现代软件开发中,多核处理器普及使多线程编程成为提升性能的关键。然而,传统同步模型在高并发下易引发死锁等问题。为此,.NET Framework引入了任务并行库(TPL)和并发集合,简化并发编程并增强代码可维护性。并发集合允许多线程安全访问,如`ConcurrentQueue&lt;T&gt;`和`ConcurrentDictionary&lt;TKey, TValue&gt;`,有效避免数据不一致。TPL则通过`Task`类实现异步操作,提高开发效率。正确使用这些工具可显著提升程序性能,但也需注意任务取消和异常处理等常见问题。
56 1
|
4月前
|
数据采集 API 开发者
.NET 8新特性:使用ConfigurePrimaryHttpMessageHandler定制HTTP请求
在.NET 8中,通过`ConfigurePrimaryHttpMessageHandler`方法,开发者能更精细地控制HTTP请求,这对于构建高效爬虫尤为重要。此特性支持定制代理IP、管理Cookie与User-Agent,结合多线程技术,有效应对网络限制及提高数据采集效率。示例代码展示了如何设置代理服务器、模拟用户行为及并发请求,从而在遵守网站规则的同时,实现快速稳定的数据抓取。
.NET 8新特性:使用ConfigurePrimaryHttpMessageHandler定制HTTP请求
|
4月前
|
JSON API C#
闲话 .NET(6):.NET Core 各个版本的特性
闲话 .NET(6):.NET Core 各个版本的特性
129 0
|
5月前
|
人工智能 开发框架 Devops
.NET技术概览:** 本文探讨了.NET的核心特性,包括多语言支持、Common Language Runtime、丰富的类库和跨平台能力,强调其在企业级、Web、移动及游戏开发中的应用。
【7月更文挑战第4天】.NET技术概览:** 本文探讨了.NET的核心特性,包括多语言支持、Common Language Runtime、丰富的类库和跨平台能力,强调其在企业级、Web、移动及游戏开发中的应用。此外,讨论了.NET如何通过性能优化、DevOps集成、AI与ML支持以及开源策略应对未来挑战,为开发者提供强大工具,共创软件开发新篇章。
63 3