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

C# 程序暂停的两种方式

 C# 程序暂停的两种方式:EventWaitHandle 与 volatile bool pause

在C#中,线程控制是多线程编程的重要组成部分,其中实现暂停的需求经常出现。本文将详细探讨使用`EventWaitHandle`和设置`volatilebool`来实现线程暂停的不同方式,它们的优缺点,以及适用场景。

1. 基本概念

 1.1 EventWaitHandle

`EventWaitHandle` 是一个用于线程间同步的类,可以用来控制线程的运行状态。它有两种状态:有信号和无信号。通过设置与重置信号状态,可以实现对线程的暂停与恢复。

### 1.2 Volatile Bool

`volatile` 关键字是C#中用于指示编译器和运行时,在多线程环境中对这个字段的访问可能会被其它线程修改。使用`volatileBool`可以简单地实现线程的暂停和恢复,通过检查该布尔值的状态来决定当前线程是否应该继续执行。


2. 实现方式

2.1 使用 EventWaitHandle

创建 `EventWaitHandle` 的实例可以使用如下代码:

Private EventWaitHandle waitHandle = new EventWaitHandle(true, EventResetMode.ManualReset);

public void WorkerThread()

{

    while (true)

    {

        waitHandle.WaitOne(); // 等待信号

        // 进行工作

    }

}


// 暂停和恢复方法

public void Pause()

{

    waitHandle.Reset(); // 设置为无信号

}


public void Resume()

{

    waitHandle.Set(); // 设置为有信号

}


在上面的代码中,`WorkerThread` 方法在每次循环开始时会检查 `waitHandle` 的状态。如果为无信号状态,线程将暂停。


 2.2 使用 volatile bool

private volatile bool isPaused = false;


public void WorkerThread()

{

    while (true)

    {

        while (isPaused)

        {

            Thread.Sleep(100); // 暂停,避免一直消耗CPU

        }

        // 进行工作

    }

}


// 暂停和恢复方法

public void Pause()

{

    isPaused = true; // 设置为暂停状态

}


public void Resume()

{

    isPaused = false; // 设置为恢复状态

}


在这个实现中,线程通过不断检查 `isPaused` 的状态来决定是否继续执行。


3. 主要区别

3.1 语义

**EventWaitHandle**提供了更明确的线程同步控制,其状态清晰且易于理解,具有强大的控制能力。

**volatile bool** 实现较为简单,适合用于简单的暂停与恢复场景。

### 3.2 性能

- `EventWaitHandle` 由于涉及到操作系统的内核态调用,可能会带来一定的性能销,但在等待状态时不会占用CPU。

- `volatile bool` 在检查条件时可能会消耗更多CPU,因为线程会在循环中进行忙等待(busy wait)直到条件改变。

### 3.3 适用场景

- 对于需要高效线程控制和强同步需求的场景,如复杂的多线程任务,推荐使用 `EventWaitHandle`。

- 对于性能要求不高,以及操作相对简单的场景,使用 `volatile bool` 可以降低代码复杂度。

### 3.4 可扩展性

- 如果需要在程序中处理多个线程的停顿和恢复,`EventWaitHandle` 可以更方便地扩展到多个线程间的同步。

- `volatile bool` 适合简化实现,但在管理多个线程时将会增加复杂性。


## 4. 使用示例

### 4.1 示例:EventWaitHandle

这是一个使用 `EventWaitHandle` 的多线程程序示例:

class Program

{

    private static EventWaitHandle waitHandle = new EventWaitHandle(true, EventResetMode.ManualReset);


    static void Main(string[] args)

    {

        Thread worker = new Thread(WorkerThread);

        worker.Start();


        // 控制暂停与恢复

        Console.WriteLine("Press Enter to pause...");

        Console.ReadLine();

        Pause();


        Console.WriteLine("Press Enter to resume...");

        Console.ReadLine();

        Resume();

    }


    static void WorkerThread()

    {

        while (true)

        {

            waitHandle.WaitOne();

            Console.WriteLine("Working...");

            Thread.Sleep(1000); // 模拟工作

        }

    }


    static void Pause()

    {

        waitHandle.Reset();

    }


    static void Resume()

    {

        waitHandle.Set();

    }

}


### 4.2 示例:Volatile Bool

以下是使用 `volatile bool` 的示例:

class Program

{

    private static volatile bool isPaused = false;


    static void Main(string[] args)

    {

        Thread worker = new Thread(WorkerThread);

        worker.Start();


        // 控制暂停与恢复

        Console.WriteLine("Press Enter to pause...");

        Console.ReadLine();

        Pause();


        Console.WriteLine("Press Enter to resume...");

        Console.ReadLine();

        Resume();

    }


    static void WorkerThread()

    {

        while (true)

        {

            while (isPaused)

            {

                Thread.Sleep(100); // 避免忙等待

            }

            Console.WriteLine("Working...");

            Thread.Sleep(1000); // 模拟工作

        }

    }


    static void Pause()

    {

        isPaused = true;

    }


    static void Resume()

    {

        isPaused = false;

    }

}


## 5. 总结


在多线程编程中,暂停和恢复线程是一个重要的功能。`EventWaitHandle` 和 `volatile bool` 各有其优缺点。选择合适的方法取决于具体情况,包括性能要求、代码复杂度和可扩展性需求。在简单情况下,可以选择`volatilebool`,但在更复杂的多线程情况中, `EventWaitHandle`提供了更为强大的支持。


相关文章:

C# 程序暂停的两种方式

C# 程序暂停的两种方式:EventWaitHandle 与 volatile bool pause 在C#中,线程控制是多线程编程的重要组成部分,其中实现暂停的需求经常出现。本文将详细探讨使用EventWaitHandle和设置volatilebool来实现线程暂停的不同方式,它们…...

【LeetCode】【算法】160.相交链表

Leetcode 160. 相交链表 题目描述 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。 思路 AB,一个指针,访问完A访问B;另一个指针&#…...

光伏破局 引领能源革命

为进一步推进商业信用体系建设,促进企业诚实守信经营,面向企业普及诚信与品牌建设的意义,指导企业加强诚信品牌建设,提升其整体竞争力,“崛起的民族品牌”专题系列节目以诚信为内涵,在全国范围内遴选出有行…...

Jenkins声明式Pipeline流水线语法示例

系列文章目录 docker搭建Jenkins2.346.3版本及常用工具集成配置(ldap、maven、ansible、npm等) docker安装低版本的jenkins-2.346.3,在线安装对应版本插件失败的解决方法 文章目录 系列文章目录jenkins流水线基础1、pipeline1.1、什么是pipeline?1.2、为什么使用pi…...

互联网技术净土?原生鸿蒙开启全新技术征程

鸿蒙生态与开发者的崭新机会 HarmonyOS NEXT承载着华为对未来操作系统的深刻理解,如今已发展为坚实的数字底座。它不仅在技术层面取得了全面突破,还在中国操作系统市场中站稳了脚跟。 当前,HarmonyOS NEXT的代码行数已超过1.1亿&#xff0c…...

关于Django 模型字段 `choices`自定义数据类型的枚举——补充

文章目录 1. 处理 datetime 类型的 choices2. 处理 time 类型的 choices3. 处理 Decimal 类型的 choices4. 处理 UUID 类型的 choices5. 处理 float 类型的 choices 在 Choices 类的基础上扩展,可以将 choices 与特定数据类型(如 date 或 datetime&a…...

CAP理论的延申--BASE理论

上一篇文章我简单介绍了一下什么是CAP理论,本篇文章讲解一下随着技术的演变,CAP理论是如何发展为BASE理论的。 CAP理论回顾 首先我们回顾一下CAP理论,CAP理论指得是分布式系统发生网络等故障时,不同节点之间无法同步数据&#xf…...

【傻呱呱】phpMyAdmin怎样给特定用户授权特定数据库权限?

前期准备 phpMyAdmin数据库(MySQL) END...

『VUE』21. 组件注册(详细图文注释)

目录 组件注册局部注册全局注册全局注册示例总结 欢迎关注 『VUE』 专栏,持续更新中 欢迎关注 『VUE』 专栏,持续更新中 组件注册 组件注册有两种方式:全局注册和局部注册。全局注册只需要注册依次,其他组件可以直接调用无需再次像局部注册一…...

如何产看SQL 查询的执行时间

要查看 SQL 查询的执行时间,尤其是毫秒级别,可以使用以下几种方法: 方法 1:使用 SET STATISTICS TIME 查看执行时间 SET STATISTICS TIME 会显示执行时间的详细信息,包括 CPU 时间和总耗时。启用后,SQL S…...

计算机网络——路由器构成

算路由表是分布式去算——你算你的,我算我的 输出队列非先来先传 调度发生在哪里 缓存队列一般是应对——来数据方向的速度过快问题...

架构师之路-学渣到学霸历程-48

实现域名跳转的实验 今天继续还是分享域名跳转的实验;继续整,看看效果 意思就是你本来访问www.liangjiawei.net的网站然后跳转到blog.liangjiawei.net的网站 1、基础的环境部署 安装好nginx(这里最好的就是干净的环境)创建两个…...

HappyChart——一款简单好用的专业绘图软件

HappyChart是一款新出的专业绘图软件,灵感来自于类PS软件,它是以图层的方式进行绘图。相比与Excel图表或其他专业绘图软件,HappyChart界面简洁明了,操作简单,没有复杂的选项,它只调整绘图相关参数即可实时展…...

【Linux】进程信号全攻略(二)

🌈 个人主页:Zfox_ 🔥 系列专栏:Linux 目录 一:🔥 再谈信号的捕捉 🦋 关于信号捕捉的细节部分(sigaction函数) 二:🔥 穿插话题 - 操作系统是怎么运…...

redis用法(二)

文章目录 02-redis数据类型篇生产环境下的redis实况图 1.全局命令redis数据存储格式set设置k-v查看当前redis的key的数量危险命令,新手请在于超老师陪同下执行为什么危险?如何正确搜索redis的key 查看库下有多少个key查询redis库信息切换redis库查看key是…...

Python-利用os,tkinter库编写一个伪恶意程序文件(Pro版)

前言:上一期我们简单学习了如何编写一个多次弹窗警告用户的exe伪恶意文件。我们知道了把Python初始文件编译为exe文件后,程序在没有Python环境的情况下也能正常运行。我们上次编写的程序仅仅只是伪造系统正在执行关机命令前的倒计时的假象,实…...

Oracle视频基础1.4.4练习

1.4.4 [dbs] 删干净上次创建的bbk ll rm -f *dbf ll rm -f spfilebbk.ora clear ll创建bbk的pfile,准备对应的目录 ll strings spfilewilson.ora | more strings spfilewilson.ora > initbbk.ora :%s/wilson/bbk :%s/*\.//g :wq ll vi initbbk.ora####### 创…...

GOF的C++软件设计模式的分类和模式名称

“GOF” 指的是 “Gang of Four”,即“四人帮”,他们是指 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides。这四位作者在其著作《Design Patterns: Elements of Reusable Object-Oriented Software》中定义了23种设计模式,这些…...

有向图的完全可达性(有向图搜索全路径的问题) C#DFs

在考察输入输出方面我觉得是道难题了 第一次遇见邻接表的数据结构该怎么声明 卡码网105 在力扣没找见完全相同的题 感觉需要多练习多复习这种类型的题 105. 有向图的完全可达性 题目描述 给定一个有向图,包含 N 个节点,节点编号分别为 1&…...

前端开发实现自定义勾选/自定义样式,可复选,可取消勾选

基于后端返回数组实现多选、复选 以下代码基于vue2&#xff0c;如果有需要React/Vue3或者其他框架代码的&#xff0c;可以通过国内直连GPT4o进行代码转换&#xff0c;转换正确率99% 前端代码如下(直接拷贝到你的vue代码即可)&#xff1a; <!-- CustomCheckboxList.vue --&g…...

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

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

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释

以Module Federation 插件详为例&#xff0c;Webpack.config.js它可能的配置和含义如下&#xff1a; 前言 Module Federation 的Webpack.config.js核心配置包括&#xff1a; name filename&#xff08;定义应用标识&#xff09; remotes&#xff08;引用远程模块&#xff0…...

Python 高效图像帧提取与视频编码:实战指南

Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...

【UE5 C++】通过文件对话框获取选择文件的路径

目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 &#xff0c;这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器&#xff0c;右键点击 .uproject 文件&#xff0c;选择 "Generate Visual Studio project files"&#xff0c;重…...

【实施指南】Android客户端HTTPS双向认证实施指南

&#x1f510; 一、所需准备材料 证书文件&#xff08;6类核心文件&#xff09; 类型 格式 作用 Android端要求 CA根证书 .crt/.pem 验证服务器/客户端证书合法性 需预置到Android信任库 服务器证书 .crt 服务器身份证明 客户端需持有以验证服务器 客户端证书 .crt 客户端身份…...