.NET 实现并行的几种方式(二)

本随笔续接:.NET 实现并行的几种方式(一) 

四、Task  

3)Task.NET 4.5 中的简易方式

在上篇随笔中,两个Demo使用的是 .NET 4.0 中的方式,代码写起来略显麻烦,这不 .NET 4.5提供了更加简洁的方式,让我们来看一下吧。

复制代码

        /// <summary>/// Task.NET 4.5 中的简易方式/// </summary>public void Demo3(){Task.Run(() =>{SetTip("简洁的代码");});Task.Run(() =>{SetTip("验证 CreationOptions 属性");}).ContinueWith((t)=> {SetTip("CreationOptions:" + t.CreationOptions.ToString());                });}

复制代码

 

五、TPL (Task Parallel Library)

TPL (任务并行库)是 .NET 4.0 中的另一个重量级模块,可以极其优雅、便捷地完成并行逻辑的编码工作。

1)Parallel.Invoke并行多个独立的Action

复制代码

        /// <summary>/// Parallel.Invoke并行多个独立的Action/// </summary>public void Demo1(){Task.Run(() =>{List<Action> actions = new List<Action>();// 生成并行任务for (int i = 0; i < 5; i++){// 注意、这里很关键,不可直接使用i变量。 // 原因在稍后的随笔中进行说明int index = i;actions.Add(new Action(() =>{SetTip(string.Format("Task{0} 开始", index));SetTip(string.Format("Task{0} 休眠1秒", index));Thread.Sleep(1000);SetTip(string.Format("Task{0} 休眠5秒", index));Thread.Sleep(5000);SetTip(string.Format("Task{0} 结束", index));}));}// 执行并行任务Parallel.Invoke(actions.ToArray());// 当上述的5个任务全部执行完毕后,才会执行该代码SetTip("并行任务执行完毕");});}

复制代码

 

2)Parallel简单的For并行

如果 Parallel.Invoke 看做是任务并行, 则 Parallel.For 则是数据并行,可方便的完成For循环并行遍历。

复制代码

        /// <summary>/// Parallel简单的For并行/// </summary>public void Demo2(){// 为了实时更新UI、将代码异步执行Task.Run(() =>{Parallel.For(1, 100, (index) =>{SetTip(string.Format("Index:{0}, 开始执行Task", index));Thread.Sleep(1000);SetTip(string.Format("Index:{0}, 开始休眠Action 1秒", index));SetTip(string.Format("Index:{0}, Task执行完毕", index));});SetTip("并行任务执行完毕");});}

复制代码

 

3)Parallel.For并行 并行中的 break、 return、 continue

break : 在 Parallel.For 中使用 ParallelLoopState.Break() 方法代替。

return: 在 Parallel.For 中使用 ParallelLoopState.Break() 方法代替。

continue : 在 Parallel.For 中直接使用 return 即可。

复制代码

        /// <summary>/// 中断Parallel.For并行/// </summary>public void Demo3(){// 为了实时更新UI、将代码异步执行Task.Run(() =>{int breakIndex = new Random().Next(10, 50);SetTip(" BreakIndex : -------------------------" + breakIndex);Parallel.For(1, 100, (index, state) =>{SetTip(string.Format("Index:{0}, 开始执行Task", index));if (breakIndex == index){SetTip(string.Format("Index:{0}, ------------------ Break Task", index));state.Break();// Break方法执行后、// 大于 当前索引的并且未被安排执行的迭代将被放弃// 小于 当前索引的的迭代将继续正常执行直至迭代执行完毕return;}Thread.Sleep(1000);SetTip(string.Format("Index:{0}, 休眠Action 1秒", index));SetTip(string.Format("Index:{0}, Task执行完毕", index));});SetTip("并行任务执行完毕");});}/// <summary>/// 终止Parallel.For并行/// </summary>public void Demo4(){// 为了实时更新UI、将代码异步执行Task.Run(() =>{int stopIndex = new Random().Next(10, 50);SetTip(" StopIndex : -------------------------" + stopIndex);Parallel.For(1, 100, (index, state) =>{SetTip(string.Format("Index:{0}, 开始执行Task", index));if (stopIndex == index){SetTip(string.Format("Index:{0}, ------------------ Stop Task", index));state.Stop();// Stop方法执行后// 整个迭代将被放弃return;}Thread.Sleep(1000);SetTip(string.Format("Index:{0}, 休眠Action 1秒", index));SetTip(string.Format("Index:{0}, Task执行完毕", index));});SetTip("并行任务执行完毕");});}

复制代码

 

4)Parallel.For并行中的数据聚合

在并行中,绝大多数委托都是在不同的线程中运行的,如果需要在并行中进行的数据共享、则需要考虑线程同步问题,然而线程同步会影响并行性能。

为了解决特定情况下的数据共享,而又不会因为线程同步而影响性能,Parallel.For 提供了解决方案:

复制代码

        /// <summary>/// Parallel.For并行中的数据聚合/// </summary>public void Demo5(){Task.Run(() =>{// 求 1 到 10 的阶乘的 和long total = 0;Parallel.For<long>(1, 10,() =>{SetTip("LocalInit");return 0;},(index, state, local) =>{SetTip("Body");int result = 1;for (int i = 2; i < index; i++){result *= i;}local += result;return local;},(x) =>{SetTip("LocalFinally");Interlocked.Add(ref total, x);});SetTip("Total : " + total);SetTip("并行任务执行完毕");});}

复制代码

MSDN备注:
对于参与循环执行的每个线程调用 LocalInit 委托一次,并返回每个线程的初始本地状态。 
这些初始状态传递到每个线程上的第一个 body 调用。 然后,每个后续正文调用返回可能修改过的状态值,传递到下一个正文调用。 
最后,每个线程上的最后正文调用返回传递给 LocalFinally 委托的状态值。 
每个线程调用 localFinally 委托一次,以对每个线程的本地状态执行最终操作。 
此委托可以被多个线程同步调用;因此您必须同步对任何共享变量的访问。

也就是说:
1) 并行中开辟的线程数 决定了 LocalInit、LocalFinally 的调用次数
2) 多个 迭代委托、Body 可能被同一个线程调用。
3) 迭代委托、Body 中的 local值,并不一定是 LocalInit 的初始值,也有可能是被修改的返回值。
4) LocalFinally 可能是被同时调用的,需要注意线程同步问题。

 

5)Parallel.ForEach并行

Parallel.ForEach算是另一种数据并行方式, 它与大家熟知的 IEnumerable<TSource> 接口结合十分紧密,是 foreach的并行版本。

复制代码

        /// <summary>/// Parallel.ForEach并行/// </summary>public void Demo6(){Task.Run(() =>{Parallel.ForEach<int>(Enumerable.Range(1, 10), (num) =>{SetTip("Task 开始");SetTip("Task 休眠" + num + "秒");Thread.Sleep(TimeSpan.FromSeconds(num));SetTip("Task 结束");});SetTip("并行任务执行完毕");});}

复制代码

 

6)Parallel.ForEach中的索引,中断、终止操作

在 Parallel.ForEach 中也可以轻易的获得其遍历的索引

 

 

        /// <summary>/// Parallel.ForEach中的索引,中断、终止操作/// </summary>public void Demo7(){Task.Run(() =>{Parallel.ForEach<int>(Enumerable.Range(0, 10), (num, state, index) =>{// num, 并行数据源中的数据项// state, SetTip(" Index : " + index + "         Num: " + num);});SetTip("并行任务执行完毕");});}

 

 

 

本随笔到此、暂告一段落。

附,Demo : http://files.cnblogs.com/files/08shiyan/ParallelDemo.zip

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/438089.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis 和 数据库mysql之间的关系

https://www.zhihu.com/question/20734566 https://www.zhihu.com/question/19660689 http://blog.csdn.net/Ideality_hunter/article/details/77621643 redis和mysql要根据具体业务场景去选型 mysql&#xff1a;数据放在磁盘redis&#xff1a;数据放在内存 redis适合放一些…

GPS/轨迹追踪、轨迹回放、围栏控制

折腾一个多月终于弄完了这个项目&#xff0c;起初都未曾接触GPS/轨迹追踪、轨迹回放、圈划围栏...等一些在百度地图或者Googel地图操作的一些业务&#xff0c;后端的业务相对来说简单点 cas单点登录&#xff0c;mongdb灵活的数据存储方式,ActiveMQ消息推送、Redis存储... 这篇…

C#.NET Thread多线程并发编程学习与常见面试题解析-1、Thread使用与控制基础

前言&#xff1a;因为平时挺少用到多线程的&#xff0c;写游戏时都在用协程&#xff0c;至于协程那是另一个话题了&#xff0c;除了第一次学习多线程时和以前某个小项目有过就挺少有接触了&#xff0c;最近准备面试又怕被问的深入&#xff0c;所以就赶紧补补多线程基础。网上已…

PWN-PRACTICE-BUUCTF-22

PWN-PRACTICE-BUUCTF-22hitcontraining_unlinkpicoctf_2018_leak_mesuctf_2018_basic pwnaxb_2019_brop64hitcontraining_unlink unlink&#xff0c;参考&#xff1a;[BUUCTF]PWN——hitcontraining_unlink # -*- coding:utf-8 -*- from pwn import * #ioprocess("./bam…

javaee, javaweb和javase的区别以及各自的知识体系

JavaSE Java SE 以前称为 J2SE。它允许开发和部署在桌面、服务器、嵌入式环境和实时环境中使用的 Java 应用程序。Java SE 包含了支持 Java Web 服务开发的类&#xff0c;并为 Java Platform&#xff0c;Enterprise Edition&#xff08;Java EE&#xff09;提供基础。 JavaE…

.NET 实现并行的几种方式(三)

在前两篇随笔中&#xff0c;先后介绍了 Thread 、ThreadPool 、IAsyncResult (即 APM系列) 、Task 、TPL (Task Parallel Library)。 写到这些笔者突然意识到 还有一个EMP系列没有写&#xff0c;在这里补充一下&#xff1a; 六、 EAP 、EAP中的典型代表是 WebClient: EAP系…

.NET异步编程之新利器——Task与Await、Async

一. FrameWork 4.0之前的线程世界     在.NET FrameWork 4.0之前&#xff0c;如果我们使用线程。一般有以下几种方式&#xff1a; 使用System.Threading.Thread 类&#xff0c;调用实例方法Start()开启一个新线程&#xff0c;调用Abort()方法来提前终止线程。使用System.T…

对比MS Test与NUnit Test框架

前言&#xff1a; 项目中进行Unit Test时&#xff0c;肯定会用到框架&#xff0c;因为这样能够更快捷、方便的进行测试。 .Net环境下的测试框架非常多&#xff0c;在这里只是对MS Test和NUnit Test进行一下比较&#xff0c; 因为这两个框架用的较多&#xff0c;也有大虾想过…

PWN-PRACTICE-BUUCTF-25

PWN-PRACTICE-BUUCTF-25wustctf2020_name_your_catciscn_2019_final_2mrctf2020_shellcode_revengezctf2016_note2wustctf2020_name_your_cat 通过数组越界覆写返回地址为后门shell的地址 from pwn import * #ioprocess(./wustctf2020_name_your_cat) ioremote(node4.buuoj.c…

使用 Github Pages 和 Hexo 搭建自己的独立博客【超级详细的小白教程】

2022-01-25 更新&#xff1a;博客新地址&#xff1a;https://www.itbob.cn/ 欢迎关注我的专栏&#xff1a;《个人博客搭建&#xff1a;HexoGithub Pages》&#xff0c;从搭建到美化一条龙&#xff0c;帮你解决 Hexo 常见问题&#xff01; 推荐阅读&#xff1a;《Hexo 博客优化…

windows程序消息机制(Winform界面更新有关)

1. Windows程序消息机制 Windows GUI程序是基于消息机制的,有个主线程维护着消息泵。这个消息泵让windows程序生生不息。 Windows程序有个消息队列&#xff0c;窗体上的所有消息是这个队列里面消息的最主要来源。这里的While循环使用了GetMessage() 这个方法,这是个阻塞方法,也…

最新主流 Markdown 编辑器推荐

Markdown &#xff0c;2004年由 John Gruberis 设计和开发&#xff0c;是一种可以使用普通文本编辑器编写的标记语言&#xff0c;通过简单的标记语法&#xff0c;它可以使普通文本内容具有一定的格式&#xff0c;以下将介绍目前比较流行的一些 Markdown 编辑器&#xff08;排名…

PWN-PRACTICE-BUUCTF-27

PWN-PRACTICE-BUUCTF-27starctf_2019_babyshellpicoctf_2018_buffer overflow 0gyctf_2020_signinbjdctf_2020_YDSneedGrirlfriendstarctf_2019_babyshell 用\x00绕过shellcode检测&#xff0c;call rdx 跳转过去执行汇编代码&#xff0c;一个\x00必执行失败 于是需要找一条机…

敏捷开发之Scrum扫盲,及敏捷开发中XP与SCRUM的区别

敏捷开发之Scrum扫盲篇 现在敏捷开发是越来越火了&#xff0c;人人都在谈敏捷&#xff0c;人人都在学习Scrum和XP... 为了不落后他人&#xff0c;于是我也开始学习Scrum&#xff0c;今天主要是对我最近阅读的相关资料&#xff0c;根据自己的理解&#xff0c;用自己的话来讲述S…

有关不蒜子访问统计无法显示的解决方法

十月初&#xff0c;不蒜子统计失效了&#xff0c;如下图&#xff1a; 进入不蒜子官网看看&#xff1a; 问题来了&#xff0c;官网写着&#xff1a;因七牛强制过期『dn-lbstatics.qbox.me』域名&#xff0c;与客服沟通无果&#xff0c;只能更换域名到『busuanzi.ibruce.info』…

SCRUM与XP区别

敏捷开发 1、敏捷的含义 敏捷开发是一种以人为核心、迭代、增量的开发方法。在敏捷开发中&#xff0c;把一个大项目分为多个相互联系&#xff0c;可独立运行的小项目&#xff0c;并分别完成&#xff0c;在此过程中软件一直处于可使用状态。 上面提到3个关键词&#xff0c;下…

Java编写程序时出现警告:Resource leak: 'xxx' is never closed 解决方案

菜鸟新手&#xff0c;学校在教Java&#xff0c;作业里面要求我们编程实现运算一个简单的程序&#xff0c;程序写好了&#xff0c;却发现冒出一个警告&#xff0c;如下图&#xff1a; 百度了一下&#xff0c;意思是申明了名为a的数据输入扫描仪&#xff08;Scanner&#xff09…

ASP.Net请求处理机制初步探索之旅 - Part 1 前奏

开篇&#xff1a;ASP.Net是一项动态网页开发技术&#xff0c;在历史发展的长河中WebForm曾一时成为了ASP.Net的代名词&#xff0c;而ASP.Net MVC的出现让这项技术更加唤发朝气。但是&#xff0c;不管是ASP.Net WebForm还是ASP.Net MVC在请求处理机制上大部分都是相同的&#xf…

ASP.Net请求处理机制初步探索之旅 - Part 2 核心

开篇&#xff1a;上一篇我们了解了一个请求从客户端发出到服务端接收并转到ASP.Net处理入口的过程&#xff0c;这篇我们开始探索ASP.Net的核心处理部分&#xff0c;借助强大的反编译工具&#xff0c;我们会看到几个熟悉又陌生的名词&#xff08;类&#xff09;&#xff1a;Http…

REVERSE-COMPETITION-0xGame2021

REVERSE-COMPETITION-0xGame2021Signin: User FriendlyInstallerOur Compilation StoryPacketRandom ChaosNeverlandRoundaboutDespacitoSecret BaseMazeZero ThreeMirrorThread_TLS茶谈室JunkertownSignin: User Friendly 64位exe&#xff0c;ida打开&#xff0c;在main函数中…