当前位置: 首页 > 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;我们该如何将它们…...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

Java - Mysql数据类型对应

Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

在四层代理中还原真实客户端ngx_stream_realip_module

一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡&#xff08;如 HAProxy、AWS NLB、阿里 SLB&#xff09;发起上游连接时&#xff0c;将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后&#xff0c;ngx_stream_realip_module 从中提取原始信息…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...