当前位置: 首页 > news >正文

【.NET Core】深入理解任务并行库 (TPL)

【.NET Core】深入理解任务并行库 (TPL)

文章目录

  • 【.NET Core】深入理解任务并行库 (TPL)
    • 一、概述
    • 二、数据并行(任务并行库)
    • 三、Parallel.For 循环示例
    • 四、Parallel.ForEach 循环示例
    • 五、处理并行循环中的异常
    • 六、数据并行总结
      • 6.1 不要假定并行的速度始终更快
      • 6.2 不要假定并行的速度始终更快
      • 6.3 避免过度并行化
      • 6.4 避免调用非线程安全方法
      • 6.5 避免调用非线程安全方法

一、概述

任务并行库(TPL)英文:Task Parallel LibrarySystem.ThreadingSystem.Threading.Tasks空间中的一组公共类型和API。TPL的目的是通过简化将并行和并发添加到应用程序的过程来提高开发人员的工作效率。TPL动态缩放并发的程度以最有效地使用所有可用的处理器。此外,TPL还处理工作分区,ThreadPool上的线程调度、取消支持、状态管理以及其他低级别的细节操作。通过使用TPL,你可以在将精力集中于程序要完成的工作,同时最大程度地提高代码的性能。

在.NET Framework4中,首选TPL编写多线程代码和并行代码。但是,并不是所有代码都适合并行化。 例如,如果某个循环在每次迭代时只执行少量工作,或它在很多次迭代时都不运行,那么并行化的开销可能导致代码运行更慢。

二、数据并行(任务并行库)

数据并行指的是对源集合或数组的元素同时(既:并发)执行相同操作的场景。在数据并行操作中,对源集合进行分区,以便对个线程能够同时在不同的网段上操作。

任务并行库(TPL)支持通过System.Threading.Tasks.Parallel类实现的数据并行。此类对for循环和foreach循环提供了基于方法的并行执行。Parallel.ForParallel.ForEach循环编写的循环逻辑与编写循环的相似。无需创建线程或列工作项。在基本循环中,不需要加锁。TPL为你处理所有低级别的工作。

下面的代码示例演示了一个简单的 foreach 循环及其并行等效项。

//Sequential version
foreach(var item in sourceCollection)
{SetMethod(item);
}
// Parallel equivalent
Parallel.ForEach(sourceCollection, item => SetMethod(item));

并行循环运行时,TPL 将数据源进行分区,以便该循环可以同时对多个部分进行作用。 在后台,任务计划程序基于系统资源和工作负荷来划分任务。 如有可能,如果工作负荷变得不平衡了,计划程序将重新分配多个线程与处理器之间的工作。

三、Parallel.For 循环示例

static void Main(string[] args)
{Stopwatch stopwatch = new Stopwatch();stopwatch.Start();char[] charList = "在验证目录存在后它需要将单个目录路径作为参数,并报告该目录中文件的数量和总大小。".ToCharArray();Parallel.For(0, charList.Length,index =>{Console.WriteLine($"index{index}");Console.WriteLine($"CharList->Char:{charList[index]}");});stopwatch.Stop();Console.WriteLine($"Run Time  {stopwatch.ElapsedMilliseconds}");stopwatch.Start();foreach ( char c in charList ){Console.WriteLine($"CharList->Char:{c}");}stopwatch.Stop();Console.WriteLine($"Run Time  {stopwatch.ElapsedMilliseconds}");Console.WriteLine("Directory Run End");Console.ReadKey();
}

For的此重载的第三个参数的类型为Action<int>。不管Action委托具有零个、一个或十六个类型参数,它都始终返回void

四、Parallel.ForEach 循环示例

static void Main(string[] args)
{var limit = 200;var numbers = Enumerable.Range(0, limit).ToList();Parallel.ForEach(numbers, number =>{Console.WriteLine(number);});Console.ReadKey();
}

Parallel.ForEach循环的工作原理类似Parallel.For循环。该循环对源集合进行分区,并根据系统环境在多个线程上安排工作。系统上的处理器越多,并行方法的运行速度就越快。对于一些源集合,有序循环可能会更快,具体根据源大小以及该循环要执行的工作类型而定。

五、处理并行循环中的异常

Parallel.ForParallel.ForEach重载没有任何用于处理可能引发异常的特性机制。在这一方面,他们类似于常规forforeach循环;未处理的异常会导致循环在当前运行的迭代完成后立即终止。

向并行循环添加自己的异常处理逻辑时,将处理类似于在多个线程上同时引发相似异常的情况,以及一个线程上引发异常导致另一个线程上引发另一个异常的情况。你可以通过将循环中的所有异常包装到一个System.AggregateException中处理这两种情况。

static void Main(string[] args)
{byte[] data = new byte[20];Random r = Random.Shared;r.NextBytes(data);var exceptions = new ConcurrentQueue<Exception>();Parallel.ForEach(data, d =>{try{if (d < 3) throw new ArgumentException($"Value is {d}. Value must be greater than or equal to 3.");else Console.Write(d + " ");}catch (Exception e){exceptions.Enqueue(e);}});Console.WriteLine();if (!exceptions.IsEmpty){throw new AggregateException(exceptions);}}
}

六、数据并行总结

在许多情况下,与普通的顺序循环相比,Parallel.ForParallel.ForEach可以显著提升性能。但是,对循环进行并行的工作增加了复杂性,可能会导致在顺序代码中出现不常见或根本不会遇到的问题。

6.1 不要假定并行的速度始终更快

在某些情况下,并行循环可能比它等效的顺序循环的运行速度更慢。 基本的经验法则是具有较少迭代和快速用户委托的并行循环未必会快很多。 但是,由于性能会涉及到很多因素,因此我们建议始终衡量实际的结果。

6.2 不要假定并行的速度始终更快

在顺序代码中,从静态变量或类字段中读取或写入静态变量或类字段的情况很常见。 但是,每当多个线程同时访问此类变量时,则很有可能会出现争用条件。 即使可以使用锁来同步对变量的访问,但同步开销可能会对性能造成损害。 因此,我们建议尽可能地避免在一个并行循环中访问共享状态,或至少限制对共享状态的访问。

6.3 避免过度并行化

通过使用并行循环,将会产生对源集合进行分区和同步工作线程的开销成本。 计算机上的处理器数量进一步限制了并行化的优点。 仅在一个处理器上运行多个受计算限制的线程时,速度并不会得到提升。 因此,必须要小心,不要对循环进行过度并行化。

在嵌套的循环中,最有可能发生过度并行化的情况。 在大多数情况下,除非满足以下一个或多个条件,否则最好仅对外部循环进行并行化:

  • 已知内部循环非常长。
  • 正在对每个订单执行开销极大的计算。
  • 已知目标系统具有足够的处理器来处理通过对 cust.Orders 上的查询进行并行化所产生的线程数。

6.4 避免调用非线程安全方法

如果从并行循环中写入非线程安全实例方法,可能会导致出现程序可能检测到也可能检测不到的数据损坏。 还可能会导致异常。

6.5 避免调用非线程安全方法

.NET 中的大多数静态方法是线程安全的,并且可以同时从多个线程中调用。 但是,即使在这些情况下,所涉及到的同步也可能会导致查询速度大幅度下降。

相关文章:

【.NET Core】深入理解任务并行库 (TPL)

【.NET Core】深入理解任务并行库 (TPL) 文章目录 【.NET Core】深入理解任务并行库 (TPL)一、概述二、数据并行&#xff08;任务并行库&#xff09;三、Parallel.For 循环示例四、Parallel.ForEach 循环示例五、处理并行循环中的异常六、数据并行总结6.1 不要假定并行的速度始…...

win10安装redis并配置加自启动(采用官方推荐unix子系统)

记录&#xff0c;为啥有msi安装包&#xff0c;还这么麻烦的用linux版本redis的安装方式&#xff0c;是因为从github上下载别人制作的msi报毒&#xff0c;还不止一处&#xff0c;这种链接数据库的东西&#xff0c;用别人加工过的&#xff0c;都报毒了还用就是傻逼了。 所以采用…...

【大数据面试题】HBase面试题附答案

目录 1.介绍下HBase 2.HBase优缺点 3.介绍下的HBase的架构 4.HBase的读写缓存 5.在删除HBase中的一个数据的时候&#xff0c;它是立马就把数据删除掉了吗? 6.HBase中的二级索引 7.HBase的RegionServer宕机以后怎么恢复的? 8.HBase的一个region由哪些东西组成? 9.…...

SpringBoot中从HikariCP迁移到Oracle UCP指南

本博客文章的目标是作为从 HikariCP 和Oracle UCP&#xff08;通用连接池&#xff09;迁移的指南&#xff0c;因为它是连接到Oracle 数据库时的推荐方法。 HikariCP 简介 HikariCP是与 Spring Boot 应用程序一起使用的 JDBC 连接池。 简而言之&#xff0c;从 Java 开发人员的…...

第3章 接口和API设计

第15条&#xff1a;用前缀避免命名空间冲突 OC没有其他语言那种内置的命名空间机制。因此&#xff0c;我们在起名时要设法避免潜在的命名冲突&#xff0c;否则很容易就重名了。若是发生重名冲突&#xff0c;那么应用程序相应的链接过程就会出错。例如&#xff1a; 错误原因在…...

HBase入门:实现原理

文章目录 说明HBase的实现原理HBase功能组件表和 RegionRegion 的定位 说明 本文参考自林子雨老师的《大数据技术原理与应用(第三版)》教材内容&#xff0c;仅供学习和交流 HBase的实现原理 HBase功能组件 HBase 的实现包括 3 个主要的功能组件&#xff1a;库函数&#xff…...

Redis入门到实战-基础篇+实战篇+高级篇+原理篇

Redis入门到实战-基础篇实战篇高级篇原理篇 文章目录 Redis入门到实战-基础篇实战篇高级篇原理篇一、基础篇二、实战篇三、高级篇四、原理篇 一、基础篇 1.基础篇笔记&#xff1a;https://blog.csdn.net/cygqtt/article/details/126974142 二、实战篇 1.实战篇笔记&#xff1a;…...

redis 工具类

在Spring Boot项目中&#xff0c;Redis是一个常用的分布式缓存解决方案。下面展示的RedisCache工具类封装了对Redis进行基本操作的方法&#xff0c;包括存储和获取各种类型的数据、设置过期时间以及处理集合类型的缓存。 /*** redis 工具类***/ SuppressWarnings(value { &q…...

焕新升级,不同以“网” | AnyCase客户端全新上线

升级啦~ 2024年1月23日 箱讯AnyCase官网全新改版上线&#xff01; 全球贸易All in One集成平台 集物流服务、外贸服务、供应链金融服务、企业风控服务、碳中和服务于一体 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 优化首页布局→体验升级 此次…...

导出 MySQL 数据库表结构、数据字典word设计文档

一、第一种 &#xff1a;利用sql语句查询 需要说明的是该方法应该适用很多工具&#xff0c;博主用的是navicat SELECT TABLE_NAME 表名,( i : i 1 ) AS 序号,COLUMN_NAME 列名, COLUMN_TYPE 数据类型, DATA_TYPE 字段类型, CHARACTER_MAXIMUM_LENGTH 长度, IS_NULLABLE…...

conda管理python安装包与虚拟环境的相关命令汇总

conda的简单介绍 Anaconda&#xff0c;是一个开源的Python发行版本&#xff0c;包含了conda、Python以及一大堆安装好的工具包及依赖项。 conda是Anaconda中的一个开源的、Python包和环境的管理工具&#xff0c;包含于Anaconda的所有版本当中。因此使用conda需要先安装Anacon…...

Vue3引用echart5 报错解决

一、TypeError: Cannot read properties of undefined (reading type) 原因&#xff1a;由于把echart实例绑定到了一个响应式的变量上 解决方案 【1】使用markRaw 把响应式变量定为非响应式变量 import { markRaw } from vue; export default {data() {return {chartConta…...

浅析HTTP协议

首先&#xff0c;前端请求后端数据&#xff0c;后端响应数据给前端&#xff0c;这是我们大家都知道的&#xff0c;那其中所涉及到的数据传输协议又是什么呢&#xff1f;这个传输规范就是我们大名鼎鼎的HTTP协议&#xff01; 什么是HTTP协议&#xff1f; HTTP&#xff08;超文本…...

etcd未授权到控制k8s集群

在安装完 K8s 后&#xff0c;默认会安装 etcd 组件&#xff0c;etcd 是一个高可用的 key-value 数据库&#xff0c;它为 k8s 集群提供底层数据存储&#xff0c;保存了整个集群的状态。大多数情形下&#xff0c;数据库中的内容没有加密&#xff0c;因此如果黑客拿下 etcd&#x…...

制作一个简单的HTML个人网站

在当今数字化的世界里&#xff0c;拥有一个个人网站已经成为了展示个人品牌、分享作品和信息的必备工具。虽然有各种复杂的内容管理系统&#xff08;CMS&#xff09;和平台可以帮助我们快速搭建个人网站&#xff0c;但对于初学者或者想要了解更多技术细节的人来说&#xff0c;从…...

头歌C语言字符数组

目录 第1关:字符逆序 任务描述 相关知识(略) 编程要求 测试说明 第2关:字符统计 任务描述 相关知识(略) 编程要求 测试说明 第3关:字符插入 任务描述 相关知识(略) 编程要求 测试说明 第4关:字符串处理 任务描述 相关知识(略)...

【mongoDB】文档 CRUD

目录 1.插入文档 批量插入&#xff1a; 2.查询文档 3.更新文档 4.删除文档 deleteOne() deleteMany() findOneAndDelete() 1.插入文档 可以使用 insert () 方法或者 save() 方法向集合中插入文档 语法如下&#xff1a; db.collection_name.insert(document) collectio…...

每日一题——LeetCode1337.矩阵中战斗力最弱的K行

方法一 个人方法 排序 题目要求就是找出每行有多少个1&#xff0c;根据每行1的个数进行排序&#xff0c;但是是把每行在数组中的位置索引进行排序&#xff0c;并返回前k项 所以先统计每行1的个数&#xff0c;并将数组转化为[index,count]就是索引加个数的数组形式&#xff0c…...

docker指令存档

目录 Docker 1、概念 2、架构图 3、安装 4、Docker怎么工作的&#xff1f; 5、Docker常用命令 帮助命令 镜像命令 1、查看镜像 2、帮助命令 3、搜索镜像 4、拉取镜像 5、删除镜像 容器命令 1、启动 2、查看运行的容器 3、删除容器 4、启动&停止 其他命令…...

Pandas ------ 向 Excel 文件中写入含有 multi-index 和 Multi-column 表头的数据

Pandas ------ 向 Excel 文件中写入含有 multi-index 和 Multi-column 表头的数据 引言正文 引言 之前在 《pandas向已经拥有数据的Excel文件中添加新数据》 一文中我们介绍了如何通过 pandas 向 Excel 文件中写入数据。那么对于含有多表头的数据&#xff0c;我们该如何将它们…...

ChatGPT 和文心一言 | 两大AI助手哪个更胜一筹

欢迎来到英杰社区&#xff1a; https://bbs.csdn.net/topics/617804998 欢迎来到阿Q社区&#xff1a; https://bbs.csdn.net/topics/617897397 &#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;致力于C/C、Java、Python等多编程语言&#xff0c;热爱跑步&#xff…...

flink学习之窗口处理函数

窗口处理函数 什么是窗口处理函数 Flink 本身提供了多层 API&#xff0c;DataStream API 只是中间的一环&#xff0c;在更底层&#xff0c;我们可以不定义任何具体的算子&#xff08;比如 map()&#xff0c;filter()&#xff0c;或者 window()&#xff09;&#xff0c;而只是…...

Python 基于pytorch从头写GPT模型;实现gpt实战

1.GPT简介 GPT&#xff08;Generative Pre-trained Transformer&#xff09;模型是一种基于Transformer架构的生成式预训练模型&#xff0c;由OpenAI开发。它采用了无监督学习的方式进行预训练&#xff0c;然后通过微调适应特定的任务。GPT模型的结构由多层Transformer解码器组…...

2023年NOC大赛(学而思赛道)创意编程Python初中组决赛真题

2023年NOC大赛&#xff08;学而思赛道&#xff09;创意编程Python初中组决赛真题 题目总数&#xff1a;7 总分数&#xff1a;100 编程题 第 1 题 问答题 二进制回文 编程实现: 输入一个正整数&#xff0c;判断它的二进制形式是否是回文数&#xff0c;如果是输出True…...

头歌C++之Switch控制语句编程实训

目录 第1关:根据输入数字判断是星期几 本关必读 本关任务 测试说明 第2关:根据输入的数值和运算符做相应运算 本关必读 本关任务 测试说明 第3关:根据输入年月计算该月份的天数 本关必读 本关任务...

CNN卷积理解

1 卷积的步骤 1 过滤器&#xff08;卷积核&#xff09;&#xff08;Filter或Kernel&#xff09;&#xff1a; 卷积层使用一组可学习的过滤器来扫描输入数据&#xff08;通常是图像&#xff09;。每个过滤器都是一个小的窗口&#xff0c;包含一些权重&#xff0c;这些权重通过训…...

DataKit迁移MySQL到openGauss

前言 本文将分享DataKit迁移MySQL到openGauss的项目实战&#xff0c;供广大openGauss爱好者参考。 1. 下载操作系统 https://www.openeuler.org/zh/download https://support.huawei.com/enterprise/zh/doc/EDOC1100332931/1a643956 https://support.huawei.com/enterprise…...

Dockerfile里ADD * 保留原来的目录结构

1、问题 给新模块写Dockerfile&#xff0c;很多静态资源分散在各个目录&#xff0c;于是Dockerfile里我直接一句&#xff1a; ADD ./* /dest/镜像出来后&#xff0c;启动容器&#xff0c;进入容器种后发现&#xff1a;文件拷贝成功&#xff0c;但原来的目录结构都不在了&…...

C++ 利用容器适配器,仿函数实现栈,队列,优先级队列(堆),反向迭代器,deque的介绍与底层

C 利用容器适配器,仿函数实现栈,队列,优先级队列【堆】,反向迭代器,deque的介绍与底层 一.容器适配器的介绍二.利用容器适配器实现栈和队列1.stack2.queue 三.仿函数介绍1.什么是仿函数2.仿函数的使用3.函数指针的使用1.函数指针的用处2.利用函数指针完成回调3.利用仿函数完成回…...

C语言实战系列二:简单超市收银系统

从一个简单的超市收银系统&#xff0c;我们来练习一个系统如何设计&#xff0c;然后如何实现的思路。 在Ubuntu环境下使用C语言编写一个简单的超市收银系统。以下是一个基本的示例&#xff0c;涵盖了商品管理、购物车、交易处理等功能。 代码 #include <stdio.h> #inc…...

空投注册送币网站怎么做/查找网站

中国领先的智能驾驶企业福瑞泰克与边缘AI芯片全球领导者地平线在2021上海车展联合发布搭载地平线征程2芯片的福瑞泰克新一代ADAS前视解决方案。 代表“智能驾驶中国力量”的双方在L2级别自动驾驶系统前装量产领域强强联手&#xff0c;未来将大幅推动中国汽车行业智能化进程加速…...

北京网站开发公司/seo是搜索引擎优化

1、必须使用支持双向通信的绑定如NetTcpBinding、NetNamedPipeBinding、WSDualHttpBinding 2、整个Contract在服务端定义(包括服务接口和回调接口);用 CallbackContract 为服务接口定义回调;服务接口在服务端实现,回调接口在客户端实现。 例&#xff1a; [ServiceContract(Call…...

做网站会遇到哪些问题/指数平台

最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南)华为od机试,独家整理 已参加机试人员的实战技巧文章目录 最近更新的博客使用说明本期…...

网站学做糕点的课程/专业seo站长工具全面查询网站

打开终端 cd ~/desktop sudo rm Flock.deb 然后输入密码就能够删除了另外的方法可以拿到nautilus的,然后就可以用文件夹窗口删除了 sudo nautilus 或者sudo gnome-open ~/desktop其实推荐pcmanfm这个文件夹管理软件,比自带的要好用,速度快,而且多标签很方便,工具菜单栏也有个以…...

焦作会计做继续教育在哪个网站/郑州网站关键词优化公司

如何在两端同时发现信息那么&#xff0c;我们如何才能完成这些功能呢&#xff1f;路由服务必须能够在网络中找到正确的信息并将其发布到另一端。我们的路由服务必须具有自动发现并控制信息的功能&#xff0c;同时也必须能够识别并处理所有的主题和类型。由于DDS对内容预知&…...

网站建设+开源/如何申请一个网站域名

作者&#xff1a;jerryWu转发连接&#xff1a;https://juejin.im/post/5ec48f84e51d45788266753apdf.js实战&#xff0c;含水印、电子签章解决方案项目涉及到移动端查看电子合同的问题&#xff0c;前前后后试了三种方案&#xff0c;真是一步一个坑&#xff0c;三种方案各有各的…...