当前位置: 首页 > 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…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

Android15默认授权浮窗权限

我们经常有那种需求&#xff0c;客户需要定制的apk集成在ROM中&#xff0c;并且默认授予其【显示在其他应用的上层】权限&#xff0c;也就是我们常说的浮窗权限&#xff0c;那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...