C# 程序暂停的两种方式

news/2024/11/5 18:07:03 标签: 个人开发

 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`提供了更为强大的支持。



http://www.niftyadmin.cn/n/5739739.html

相关文章

[免费]基于Python的Django+Vue3在线考试系统【论文+源码+SQL脚本】

大家好,我是java1234_小锋老师,看到一个不错的基于Python的DjangoVue3在线考试系统,分享下哈。 项目视频演示 【免费】基于Python的DjangoVue3在线考试系统 Python毕业设计_哔哩哔哩_bilibili 项目介绍 本论文提出并实现了一种基于Python…

高级java每日一道面试题-2024年10月28日-RabbitMQ篇-RabbitMQ的使用场景有哪些?

如果有遗漏,评论区告诉我进行补充 面试官: RabbitMQ的使用场景有哪些? 我回答: RabbitMQ是一个开源的消息代理和队列服务器,它遵循高级消息队列协议(AMQP)。RabbitMQ的核心作用是作为应用程序之间的中介,实现异步消息传递。它…

Day 42 || 完全背包、518. 零钱兑换 II 、 377. 组合总和 Ⅳ、70. 爬楼梯 (进阶)

完全背包 题目链接:卡码网第52题 思路:和之前01背包一样,但是物品可以无限放置,所以之前二维数组中的背包容量是倒序遍历的,现在可以正序遍历即可重复放入。 import java.util.Scanner; public class Main {public …

《Python编程快速上手》第一天---前三章打基础

第一章 Python基础 1、新的数学操作符 ** :指数操作 //:整除 /:除法 2、字符串连接和复制 连接:“” 例如:“Alice”“Bobby” > “AliceBobby” 复制:“*” 例如:“Alice” * 5 > “…

[linux]docker快速入门

安装 docker官网: CentOS | Docker Docs 准备工作: 准备ConstOS7的虚拟机环境账密: root/root飞书文档: Docs 卸载旧版本 // 首先如果系统中已经存在旧的Docker,则先卸载 yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest…

情怀系列国际版棋牌完整源码具备强大的多语言扩展功能,涵盖了900多款子游戏,专为全球市场的游戏开发和运营设计。

情怀棋牌源代码的服务器端使用JAVA和Node.js开发,采用RocketMQ作为消息队列中间件,有效防止服务器堵塞、消峰。数据库使用MySQL,媒体存储采用MongoDB,缓存系统使用Redis。管理后台则采用PHP语言开发。 客户端使用Cocos Creator进…

DDR5内存售价暴降80%,终于到了无脑下手的时候

DDR5 内存刚面世那会儿,大家吐槽最多的便是频率低、延迟高、价格还死贵死贵。 前两年首批 DDR5 内存频率多集中在 4800、5200、5600MT/s 等入门水平。 延迟高、游戏性能不如高频 DDR4 内存的同时,单条 16G 售价普遍来到 1000 元开外,部分 3…

Matlab实现鲸鱼优化算法优化随机森林算法模型 (WOA-RF)(附源码)

目录 1.内容介绍 2.部分代码 3.实验结果 4.内容获取 1内容介绍 鲸鱼优化算法(Whale Optimization Algorithm, WOA)是受座头鲸捕食行为启发而提出的一种新型元启发式优化算法。该算法通过模拟座头鲸围绕猎物的螺旋游动和缩小包围圈的方式,在…