[原创][4]探究C#多线程开发细节-“初步体验ManualResetEvent类带来的同步效果“

2023-12-05

[简介]
常用网名: 猪头三
出生日期: 1981.XX.XX
个人网站: 80x86汇编小站 https://www.x86asm.org
编程生涯: 2001年~至今[共22年]
职业生涯: 20年
开发语言: C/C++、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python
开发工具: Visual Studio、Delphi、XCode、Eclipse、C++ Builder
技能种类: 逆向 驱动 磁盘 文件
研发领域: Windows应用软件安全/Windows系统内核安全/Windows系统磁盘数据安全/macOS应用软件安全
项目经历: 磁盘性能优化/文件系统数据恢复/文件信息采集/敏感文件监测跟踪/网络安全检测

[序言]
为了优化" [原创][3]探究C#多线程开发细节-“用ConcurrentQueue<T>解决多线程的无顺序性的问题“-CSDN博客 "文章里面的代码示例, 需要专门为"ManualResetEvent类"写一篇文章. 只有解了 "ManualResetEvent类" 的作用, 才会知道如何优化.

[为什么要优化"[原创][3]探究C#多线程开发细节-"用ConcurrentQueue<T>解决多线程的无顺序性的问题""文章里面的代码示例?]
如果认真阅读了代码, 就会发现, 在进行多线程同步的时候, 竟然使用了for循环+Sleep()组合来实现轮询. 这是非常不友好的行为. 这里有一个弊端:for循环会不断的消耗CPU资源, 虽然通过Sleep(5)这样极短的休眠时间降低CPU的使用率, 但仅仅是给软件使用者造成一种假象. 但实际上, 把时间放大到1秒钟, 这个for循环要执行200次, 给CPU的负担也不小的.

[为了避免for循环+Sleep()这样初级的写法, 可以使用ManualResetEvent类解决.]
那么ManualResetEvent类的作用和效果是如何的呢?可以把ManualResetEvent类看作是一个红绿灯, 当ManualResetEvent类处于红灯状态的时候, 线程执行等待, 不允许执行. 当ManualResetEvent类处于绿灯状态, 线程就恢复执行状态, 继续上一次操作. 好比现实中的红绿灯过马路的效果.下面简单的看看ManualResetEvent类的使用方法

1> ManualResetEvent event_ControlThread = new ManualResetEvent(false); // 创建一个ManualResetEvent类, 并设置false(即红灯状态)
2> event_ControlThread.WaitOne(); // 等待并阻塞. 如果是红灯状态, 该代码就阻塞着, 不给线程执行event_ControlThread.WaitOne()之后的任何代码. 反之, 绿灯状态, 线程可以继续往下执行.
3> event_ControlThread.Reset();   // 等当前状态是处于绿灯状态的时候, 如果恢复为红灯状态, 那就执行一次Reset()操作.
4> event_ControlThread.Set();     // 如果当前状态处于红灯状态, 通过Set()一次, 就会变成绿灯状态, 随后绿灯灭掉. 最终的效果就是灯灭了. 因此为了保持灯处于亮灯状态, 一定要通过Reset()操作复原.

[如果理解上面的所说的, 可以尝试下一个例子]
1> 启动Visual Studio Enterprise 2022版本
2> 建立一个C# Windows窗体应用(.NET Framework).
3> 然后在窗体上放上两个按钮和一个Lable控件
4> 按钮1  : 启动一个带有for循环的线程, 然后这个for循环可以针对变量int_Count进行+1操作
5> 按钮2 : 调用event_ControlThread.Set()处理, 每单击一次, for循环线程才能运行一次.
完成上面的步骤之后, 模仿下面的代码, 抄写到你建立的项目中.

    public partial class Form_Event_Demo : Form
    {
        private int mpr_int_Count = 0;
        // private AutoResetEvent event_ControlThread = new AutoResetEvent(false);
        private ManualResetEvent event_ControlThread = new ManualResetEvent(false); // 创建事件并初始化为红灯状态

        public Form_Event_Demo()
        {
            InitializeComponent();
        }

        // 启动循环 +1 线程
        private void Bn_StartThread_Click(object sender, EventArgs e)
        {
            Thread class_LoopThread = new Thread(() =>
            {
                for (int int_Index = 0; int_Index < 10; int_Index++)
                {
                    event_ControlThread.WaitOne(); // 等待事件信号(即等待亮绿灯)

                    mpr_int_Count++;

                    // 界面显示结果
                    if (lb_Result.InvokeRequired)
                    {
                        this.Invoke((MethodInvoker)delegate {

                            lb_Result.Text = $"当前结果: {mpr_int_Count}";

                        });
                    }
                    else
                    {
                        lb_Result.Text = $"当前结果: {mpr_int_Count}";
                    }

                    event_ControlThread.Reset(); // 手动重置信号(即把灭灯状态恢复为红灯状态)
                }
            });
            class_LoopThread.Start();

        }// End Bn_StartThread_Click()

        private void Bn_Increment_Click(object sender, EventArgs e)
        {
            event_ControlThread.Set(); //设置信号(即把红灯切换为绿灯, 然后再灭灯), 通知线程执行一次循环
        }// End Bn_Increment_Click()

    }

[代码还可以在优化一下, ManualResetEvent()可以替换为AutoResetEvent(), 这样更加自动化]
AutoResetEvent()的好处就是, 如果灭灯状态, 它会自动帮你恢复为亮灯状态, 而不需要手工去Reset()一次操作.

[结尾]
这次内容看起来很简单, 但是必须要用心体会到它的工作原理和效果, 只有体验到了同步效果, 才会写出更好的多线程并发程序. 大家如果阅读完这篇文章, 有更多疑问可以留言, 有更好的建议和想法,也可以留下你的评论.

[效果演示]

初步体验ManualResetEvent类带来的同步效果

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[原创][4]探究C#多线程开发细节-“初步体验ManualResetEvent类带来的同步效果“ 的相关文章

  • Mono 无法保存用户设置

    我在 Mono Ubuntu 上保存用户设置时遇到问题 这是代码示例 private void Form1 Load object sender EventArgs e string savedText Properties Setting
  • 添加对共享类的多个 WCF 服务的服务引用

    我正在尝试将我的 WCF Web 服务拆分为几个服务 而不是一个巨大的服务 但是 Visual Studio Silverlight 客户端 复制了两个服务共享的公共类 这是一个简单的例子来说明我的问题 在此示例中 有两个服务 两者都返回类
  • 当我单击 C# 中的“取消”按钮时重定向到新页面(Web 部分)

    Cancel button tc new TableCell btnCancel new Button btnCancel Text Cancel btnCancel Click new EventHandler btnCanel Clic
  • 捕获 foreach 条件中抛出的异常

    我有一个foreach在 foreach 本身的条件下循环期间中断的循环 有没有办法try catch抛出异常然后继续循环的项 这将运行几次 直到异常发生然后结束 try foreach b in bees exception is in
  • 处理 fanart.tv Web 服务响应 JSON 和 C#

    我正在尝试使用 fanart tv Webservice API 但有几个问题 我正在使用 Json Net Newtonsoft Json 并通过其他 Web 服务将 JSON 响应直接反序列化为 C 对象 这里的问题是元素名称正在更改
  • std::map 和二叉搜索树

    我读过 std map 是使用二叉搜索树数据结构实现的 BST 是一种顺序数据结构 类似于数组中的元素 它将元素存储在 BST 节点中并按其顺序维护元素 例如如果元素小于节点 则将其存储在节点的左侧 如果元素大于节点 则将其存储在节点的右侧
  • 调试内存不足异常

    在修复我制作的小型 ASP NET C Web 应用程序的错误时 我遇到了 OutOfMemoryException 没有关于在哪里查看的提示 因为这是一个编译时错误 如何诊断此异常 我假设这正是内存分析发挥作用的地方 有小费吗 Thank
  • 范围和临时初始化列表

    我试图将我认为是纯右值的内容传递到范围适配器闭包对象中 除非我将名称绑定到初始值设定项列表并使其成为左值 否则它不会编译 这里发生了什么 include
  • 通过不同 DLL 或 EXE 中的指针或引用访问 STL 对象时发生访问冲突

    我在使用旧版 VC6 时遇到以下问题 我只是无法切换到现代编译器 因为我正在处理遗留代码库 http support microsoft com kb 172396 http support microsoft com kb 172396
  • 组合框项目为空但数据源已满

    将列表绑定到组合框后 其 dataSource Count 为 5 但组合框项目计数为 0 怎么会这样 我习惯了 Web 编程 而且这是在 Windows 窗体中进行的 所以不行combo DataBind 方法存在 这里的问题是 我试图以
  • “MyClass”的类型初始值设定项引发异常

    以下是我的Windows服务代码 当我调试代码时 我收到错误 异常 CSMessageUtility CSDetails 的类型初始值设定项引发异常 using System using System Collections Generic
  • C# using 语句、SQL 和 SqlConnection

    使用 using 语句 C SQL 可以吗 private static void CreateCommand string queryString string connectionString using SqlConnection c
  • 如何排列表格中的项目 - MVC3 视图 (Index.cshtml)

    我想使用 ASP NET MVC3 显示特定类型食品样本中存在的不同类型维生素的含量 如何在我的视图 Index cshtml 中显示它 an example 这些是我的代码 table tr th th foreach var m in
  • Qt - 设置不可编辑的QComboBox的显示文本

    我想将 QComboBox 的文本设置为某些自定义文本 不在 QComboBox 的列表中 而不将此文本添加为 QComboBox 的项目 此行为可以在可编辑的 QComboBox 上实现QComboBox setEditText cons
  • 过期时自动重新填充缓存

    我当前缓存方法调用的结果 缓存代码遵循标准模式 如果存在 则使用缓存中的项目 否则计算结果 在返回之前将其缓存以供将来调用 我想保护客户端代码免受缓存未命中的影响 例如 当项目过期时 我正在考虑生成一个线程来等待缓存对象的生命周期 然后运行
  • 是否有一个 C++ 库可以从 PDF 文件中提取文本,例如 PDFBox for Java? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 去年 我使用 PDFBox 在 Java 中创建了一个应用程序来获取某些 PDF 文件中的原始文本 现在
  • 为什么我使用google'smtp'无法发送电子邮件?

    我有以下程序使用 smtp gmail com 587 发送电子邮件 namespace TestMailServer class Program static void Main string args MailMessage mail
  • 同时从多个流中捕获、最佳方法以及如何减少 CPU 使用率

    我目前正在编写一个应用程序 该应用程序将捕获大量 RTSP 流 在我的例子中为 12 个 并将其显示在 QT 小部件上 当我超过大约 6 7 个流时 问题就会出现 CPU 使用率激增并且出现明显的卡顿 我认为它不是 QT 绘制函数的原因是因
  • 过度使用委托对性能来说是一个坏主意吗? [复制]

    这个问题在这里已经有答案了 考虑以下代码 if IsDebuggingEnabled instance Log GetDetailedDebugInfo GetDetailedDebugInfo 可能是一个昂贵的方法 因此我们只想在调试模式
  • 在基类集合上调用派生方法

    我有一个名为 A 的抽象类 以及实现 A 的其他类 B C D E 我的派生类持有不同类型的值 我还有一个 A 对象的列表 abstract class A class B class A public int val get privat

随机推荐

  • 超越其它所有SOTA!Drive-WM:与现有端到端规划兼容的第一个自动驾驶世界模型!...

    点击下方 卡片 关注 自动驾驶之心 公众号 ADAS巨卷干货 即可获取 gt gt 点击进入 自动驾驶之心 世界模型 技术交流群 论文作者 汽车人 编辑 自动驾驶之心 最近世界模型的工作好多 今天分享一个与现有端到端规划模型兼容的驾驶世界模
  • 【vue3】elementplus日期组件英文转中文

    vue3 elementplus日期组件英文转中文 1 在main js或者main ts中加入 即可解决 import ElementPlus from element plus import element plus dist inde
  • 自定义软件APP定制开发的优势|企业网站小程序搭建

    自定义软件APP定制开发的优势 企业网站小程序搭建 随着科技的不断进步和智能手机的普及 移动应用程序 APP 成为了人们生活中必不可少的一部分 对于企业来说 拥有一个自定义的APP可以带来很多优势 本文将介绍自定义软件APP定制开发的一些优
  • CnosDB FDW:打通一扇通往PostgreSQL世界的大门

    本文档提供了下载 安装和使用 CnosDB FDW 的简要说明 请根据您的实际需求和环境对文档进行调整 概述 CnosDB FDW 是一个用于在 PostgreSQL 数据库中访问 CnosDB 数据库的外部数据包装器 Foreign Da
  • 艾瑞:央国企数字化升级,低代码首选得帆云!

    中国权威咨询机构艾瑞咨询最新发布了 2023年央国企数字化升级研究报告 THE NEW RESEARCH 报告认为 央国企作为中国特色社会主义的重要物质基础和政治基础 肩负着推动经济发展和增强社会价值的重要责任 必须在数字化升级中发挥引领作
  • 事件代理如何使用?

    事件代理是一种机制 用于处理动态添加的元素或大量元素的事件绑定 通过将事件绑定到它们的父元素上 可以统一处理子元素的事件 以提高性能和代码简洁度 在jQuery中 可以使用on 方法来实现事件代理 on 方法接受两个参数 事件类型和处理函数
  • 巧借C++算法实现冒泡排序算法

    目录 引言 冒泡排序原理 具体实现步骤 示例代码 时间复杂度和稳定性 优化可能性 结束语 引言 作为计算机专业出身的开发者 以及从事软件开发相关的小伙伴 想必对C 语言并不陌生 它是一门非常厉害的编程语言 不仅是基于程序底层的语言 而且是一
  • 命令行客户端MySQL如何使用

    MySQL是一种常用的关系型数据库管理系统 它提供了命令行客户端来与数据库进行交互 以下是使用命令行客户端MySQL的基本步骤 打开命令行终端 如Windows的命令提示符或Mac的终端 输入以下命令来连接到MySQL服务器 mysql u
  • 自动驾驶轨迹/行为/运动/交通预测综述论文总结

    作者 eyesighting 编辑 汽车人 原文链接 https zhuanlan zhihu com p 664213622 点击下方 卡片 关注 自动驾驶之心 公众号 ADAS巨卷干货 即可获取 点击进入 自动驾驶之心 轨迹预测 技术交
  • Java入门:二.安装Apache Tomcat(非必须)

    前言 如果不需要使用Web服务器功能 只使用Java开发 那则不需要安装Tomcat 在安装Tomcat前 需完成java环境搭建 参见 Java入门 一 开发环境搭建 安装java jdk CSDN博客 一 下载Tomcat 下载地址 A
  • 容器与集群——通过deployment 创建pod以及Java Web应用的容器化发布

    一 通过deployment 创建pod 1 1 编写yaml文件 1 2 安装pod 创建 kubectl create f dp nginx yaml 查看Deployment信息 1 3 查看相关信息 查看pod信息 kubecel
  • 头歌—Hive的安装与配置

    第1关 Hive的安装与配置 在修改 conf 下面的 hive site xml 文件这里 题目给的信息是错误的 正确的内容如下
  • 【已解决】为什么Word文档里有部分内容无法编辑?

    小伙伴们是否遇到过这样的情况 打开Word文档进行编辑 发现部分内容可正常编辑 另外一部分内容却无法编辑 这是怎么回事 又要如何解决呢 出现以上情况 一般是Word文档被设置了 限制保护 使其部分内容被锁定 无法进行修改编辑 我们可以在文档
  • Python入门实战 | 第二期(input输入语句和if判断语句)

    本期继续给大家推荐Python的语法讲解 Python作为深度学习的必备工具 也是PHM初学者的必备技能 之前发表了初学者必看 Python入门语法讲解与实战 一 这期主要是介绍Python的input输入语句和判断语句 目录 一 inpu
  • SMT贴片加工组装工艺的可靠性

    随着电子产品的广泛应用 电子产品的可靠性已成为一个重中之重的问题 大多应用场合都要求电子产品的性能必须稳定 可靠并且能够安全的运行 在航空航天 军事 通信 金融 监控等领域 如果电子系统发生故障会对其造成很大的损失 电子产品种类复杂 由材料
  • 油气罐防雷和化工防雷综合解决方案

    油气罐防雷和化工防雷是化工企业安全生产的重要内容 涉及到化工装置 储罐 管道 电气设施等多个方面 地凯科技 将介绍油气罐防雷和化工防雷的方案和应用方案 以期为化工企业提供一些参考 油气罐防雷 油气罐是储存可燃易爆物质的设施 一旦遭受雷击 可
  • JavaScript对象的创建方式有几种?

    在JavaScript中 有多种方式可以创建对象 包括以下几种 对象字面量 Object Literals 这是创建对象最简单的方式 使用花括号 来定义对象 通过键值对的方式来定义对象的属性和方法 let person name John
  • 拼图软件合成照片有推荐吗?探索热门拼图软件

    嘿伙计 你知道吗 最近我发现了一个超级好玩的拼图软件 简直就是我网上冲浪的新宠啊 我得给你分享一下我在这个软件上的使用体验感 简直是让我笑翻了 拼图的时候 你可以像变魔术一样通过手指滑动 缩放 旋转 将碎片们拼接起来 就像魔法一样 一块块碎
  • linux下安装nginx

    第一步 压缩包 准备压缩包 最好准备一个稳定的版本 下载地址 我这边选用的是1 24 0双版本号 第二步 解压 在相对应的目录下 执行命令 tar zxvf nginx 1 18 0 tar gz 第三步 配置 编译 推荐使用 config
  • [原创][4]探究C#多线程开发细节-“初步体验ManualResetEvent类带来的同步效果“

    简介 常用网名 猪头三 出生日期 1981 XX XX 个人网站 80x86汇编小站 https www x86asm org 编程生涯 2001年 至今 共22年 职业生涯 20年 开发语言 C C 80x86ASM PHP Perl O