环保网站怎么做,贵阳网站制作策划,幽灵按钮网站,网页公司制作在学习的过程中#xff0c;看一些一线的技术文档很吃力#xff0c;而且考虑到国内那些技术牛人英语都不差的#xff0c;要向他们看齐#xff0c;所以每天下班都在疯狂地背单词#xff0c;博客有些日子没有更新了#xff0c;见谅见谅 什么是TPL?Task Parallel Library (T… 在学习的过程中看一些一线的技术文档很吃力而且考虑到国内那些技术牛人英语都不差的要向他们看齐所以每天下班都在疯狂地背单词博客有些日子没有更新了见谅见谅 什么是TPL?Task Parallel Library (TPL), 在.NET Framework 4微软推出TPL并把TPL作为编写多线程和并行代码的首选方式但是在国内到目前为止好像用的人并不多。TPL是System.Threading和System.Threading.Tasks命名空间中的一组公共类型和API 。TPL的目的是通过简化向应用程序添加并行性和并发性的过程来提高开发人员的工作效率,TPL动态地扩展并发度以最有效地使用所有可用的处理器。通过使用TPL您可以最大限度地提高代码的性能让我们专注于程序本身而不用去关注负责的多线程管理。出自 https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/task-parallel-library-tpl为什么使用TPL?在上面介绍了什么是TPL可能大家还是云里雾里不知道TPL的好处到底是什么。我在youtube上找到了一个优秀的视频讲述的是TPL和Thread的区别我觉得对比一下TPL的优势很快就能体现出来如果大家能打开的话建议大家一定要看看。地址是https://www.youtube.com/watch?vNo7QqSc5cl8现如今我们的电脑的CPU怎么也是2核以上下面假设我的电脑是四核的我们来做一个实验。使用Thread代码中如果使用Thread来处理任务如果不做特出的处理只是thread.Start(),监测电脑的核心的使用情况是下面这样的。每一条线代表CPU某个核心的使用情况明显随着代码Run起来其实只有某一个核心的使用率迅速提升其他核心并无明显波动为什么会这样呢 原来默认情况下操作系统并不会调用所有的核心来处理任务即使我们使用多线程其实也是在一个核心里面运行这些Thread,而且Thread之间涉及到线程同步等问题其实效率也不会明显提高。使用TPL在代码中引入了TPL来处理相同的任务再次监视各个核心的使用情况效果就变得截然不同如下。可以看到各个核心的使用情况都同时有了明显的提高。说明使用TPL后不再是使用CPU的某个核心来处理任务了而是TPL自动把任务分摊给每个核心来处理处理效率可想而知理论上会有明显提升的为什么说理论上和使用多线程一样各个核心之间的同步管理也是要占用一定的效率的所以对于并不复杂的任务使用TPL可能适得其反。实验结果出自https://www.youtube.com/watch?vNo7QqSc5cl8看了这个实验讲解是不是理解了上面所说的这句。TPL的目的是通过简化向应用程序添加并行性和并发性的过程来提高开发人员的工作效率,TPL动态地扩展并发度以最有效地使用所有可用的处理器。 所以说使用TPL 来处理多线程任务可以让你不必吧把精力放在如何提高多线程处理效率上因为这一切TPL 能自动地帮你完成。TPL Dataflow?TPL处理Dataflow是TPL强大功能中的一种它提供一套完整的数据流组件这些数据流组件统称为TPL Dataflow Library那么在什么场景下适合使用TPL Dataflow Library呢官方举的一个 栗子 再恰当不过例如通过TPL Dataflow提供的功能来转换图像,执行光线校正或防红眼可以创建管道数据流组件,管道中的每个功能可以并行执行并且TPL能自动控制图像流在不同线程之间的同步不再需要Thread 中的Lock。TPL数据流库由Block组成Block是缓冲和处理数据的单元TPL定义了三种最基础的Block。source blocksSystem.Threading.Tasks.Dataflow.ISourceBlock TOutput源块充当数据源并且可以从中读取。target blocksSystem.Threading.Tasks.Dataflow.ITargetBlock TInput,目标块充当数据接收器并可以写入。propagator blocksSystem.Threading.Tasks.Dataflow.IPropagatorBlock TInputTOutput传播器块充当源块和目标块并且可以被读取和写入。它继承自ISourceBlock TOutput和ITargetBlock TInput。 还有其他一些个性化的Block,但其实他们都是对这三种Block进行一些扩充可以结合下面的代码来理解这三种Block.Code Show1.source block 和 target block 合并成propagator block.可以看到我定义了BufferBlock和ActionBlock它们分别继承于ISourceBlock 和 ITargetBlock ,所以说他们其实就是源块和目标块在new actionBlock()中传入了一个ActionString,该Action就是该Block所执行的任务。 最后DataflowBlock.Encapsulate(actionBlock, bufferBlock)把源块和目标块合并成了一个传递块。2.TransformBlockTransfromBlock继承了IPropagatorBlock所以它本身就是一个传递块所以它除了要处理出入数据还要返回数据所以给new TransformBlock()中传入的是FuncTInput, TOutput而不是ActionTInput. 3.TargetBlock来收尾TargetBlock只能写入并处理数据不能读取所以TargetBlock适合作为Pipeline的最后一个Block。 4.控制每个Block的并行度在在构造TargetBlock(包括其子类)的时候可以传入ExecutionDataflowBlockOptions参数ExecutionDataflowBlockOptions对象里面有一个MaxDegreeOfParallelism属性通过改制可以控制该Block的同时处理任务的数量可以理解成线程数。5.构建Pipeline,连接Block通过ISourceBlockTOutput.LinkTo(ITargetBlockTOutput target, DataflowLinkOptions linkOption)方法可以把Block连接起来即构建Pipeline当DataflowLinkOptions对象的PropagateCompletion属性为true时SorceBlock任务处理完成是会把TargetBlock也标记为完成。 Block被标记为Complete 后无法传入新的数据了即不能再处理新的任务了。 6.Pipeline的运行Pipeline构建好后我们只需要给第一个Block传入数据该数据就会在管道内流动起来了所有数据传入完成后调用Block的Complete方法把该Block标记为完成就不可以再往里面Post数据了。测试运行如图我来解释一下为什么是这么运行的因为把管道的并行度设置为2所以每个Block可以同时处理两个任务所以,如果给管道传入四个字符 每个字符作为一个任务假设传入 “码农阿宇”四个任务会时这样的一个过程…..码 农 两个首先进入Process1,处理完成后码 农 两个任务流出Process1位置空出来 阿 宇 两个任务流入 Process1,码 农 两个任务流向 Process2阿 宇 从 Process1 处理完成后流出此时Process1任务完成码 农 流出 Process2 同时 阿 宇 流入 Process2 ……依此类推…. 该项目Github地址 https://github.com/liuzhenyulive/Tpl-Dataflow-Demo参考文献https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/dataflow-task-parallel-library原文地址: https://www.cnblogs.com/CoderAyu/p/9757389.html.NET社区新闻深度好文欢迎访问公众号文章汇总 http://www.csharpkit.com