C# ManualResetEvent 类的用法

本文详细解释了C#中ManualResetEvent类的功能和使用方法,通过实例展示了如何利用ManualResetEvent对象实现线程间的信号控制,包括设置事件状态、等待事件和释放事件等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先说是一下 ManualResetEvent 是一线程用来控制别一个线程的信号。大家可以把它看成 操作系统原理中说到的pv操作

如下图所说是 ManualResetEvent 对象起一个信使的作用。

ManualResetEvent 对象的两个控制方法。
1、this.manualEvent.Reset(); //将事件状态设置为非终止状态,导致线程阻止。
2、this.manualEvent.Set(); //将事件状态设置为终止状态,允许一个或多个等待线程继续。

说了这么多光说不做还真没有用,接下来看代码!

class MyThread

        {

            Thread t = null;

            ManualResetEvent manualEvent = new ManualResetEvent(true);//为trur,一开始就可以执行

            private void Run()

            {

                while (true)

                {

                    this.manualEvent.WaitOne();

                    Console.WriteLine("这里是  {0}", Thread.CurrentThread.ManagedThreadId);

                    Thread.Sleep(5000);

                }

            }

            public void Start()

            {

                this.manualEvent.Set();

            }

            public void Stop()

            {

                this.manualEvent.Reset();

            }

            public MyThread()

            {

                t = new Thread(this.Run);

                t.Start();

            }

        }

在 main 方法中要用到上面的类

static void Main(string[] args)

        {

            MyThread myt = new MyThread();

            while (true)

            {

                Console.WriteLine("输入 stop后台线程挂起 start 开始执行!");

                string str = Console.ReadLine();

                if (str.ToLower().Trim() == "stop")

                {

                    myt.Stop();

                }

                if (str.ToLower().Trim() == "start")

                {

                    myt.Start();

                }

            }

        }

原理就说完了我们来看一下程序运行的结果!

文章转载自C# ManualResetEvent 类的用法,感谢作者 蒋乐兴 提供好文章

<think>嗯,用户想了解C#ManualResetEvent使用方法。首先,我需要回顾ManualResetEvent的基本概念和用途。根据引用[1],ManualResetEvent是用于线程间通信的工具,似于信号量。它有两种状态:终止和非终止。当处于终止状态时,允许线程继续执行;非终止状态则阻塞线程。 接下来,用户需要示例和说明。我需要确保代码示例正确,并且符合C#语法。比如初始化实例时,参数是bool型,引用[3]和[4]提到false表示初始为非终止状态。这样线程在开始时会被阻塞,直到调用Set方法。 还要解释主要方法,比如Set、Reset和WaitOne。引用[4]指出Set将状态设为终止,允许线程继续,而Reset则相反。WaitOne用于阻塞当前线程,直到事件变为终止状态。 另外,需要区分ManualResetEvent和AutoResetEvent的不同。引用[2]提到两者的异同,特别是AutoResetEvent在释放一个线程后会自动重置,而ManualResetEvent需要手动调用Reset。这一点在示例中要体现出来,比如多个线程被同时释放的情况。 用户可能关心实际应用场景,比如多线程任务的协调。比如主线程控制多个工作线程的开始,或者等待所有线程完成。这时候ManualResetEvent可以有效地同步线程。 还要注意线程安全问题,确保在正确的时机调用Set和Reset,避免死锁或竞态条件。例如,在初始化时设置为false,主线程准备好后调用Set,工作线程才能继续执行。 最后,生成的相关问题需要覆盖初始化参数的作用、与AutoResetEvent的区别、适用场景以及线程阻塞机制。这些能帮助用户更全面地理解ManualResetEvent使用和原理。</think>### C# ManualResetEvent 使用说明及示例 ManualResetEventC# 中用于线程同步的关键工具,通过信号机制控制线程的阻塞与唤醒[^1][^4]。以下是其核心使用方法和示例: --- #### **1. 基本概念** - **终止状态**:当状态为 `true` 时,所有调用 `WaitOne()` 的线程不会被阻塞。 - **非终止状态**:当状态为 `false` 时,所有调用 `WaitOne()` 的线程会被阻塞,直到状态变为 `true`。 --- #### **2. 核心方法** | 方法 | 作用 | |-----------|--------------------------------------------------------------------| | `Set()` | 将状态设置为终止状态(`true`),释放所有被阻塞的线程[^2]。 | | `Reset()` | 将状态重置为非终止状态(`false`),后续线程调用 `WaitOne()` 时会被阻塞。 | | `WaitOne()`| 阻塞当前线程,直到事件变为终止状态(可设置超时时间)。 | --- #### **3. 使用示例** ##### **场景:主线程控制工作线程的启动** ```csharp using System; using System.Threading; class Program { private static ManualResetEvent _mre = new ManualResetEvent(false); // 初始为非终止状态[^3] static void Main() { Thread workerThread = new Thread(DoWork); workerThread.Start(); Console.WriteLine("主线程准备就绪后按回车键通知工作线程"); Console.ReadLine(); _mre.Set(); // 释放工作线程 workerThread.Join(); } static void DoWork() { Console.WriteLine("工作线程等待信号..."); _mre.WaitOne(); // 阻塞直到收到信号[^2] Console.WriteLine("工作线程开始执行任务"); } } ``` ##### **输出结果** ``` 主线程准备就绪后按回车键通知工作线程 工作线程等待信号... (用户按回车键) 工作线程开始执行任务 ``` --- #### **4. 关键特性** 1. **手动重置**:调用 `Set()` 后需显式调用 `Reset()` 才能恢复阻塞状态,与 `AutoResetEvent` 自动重置不同[^2]。 2. **多线程唤醒**:一次 `Set()` 可释放所有被阻塞的线程,适用于批量任务协调。 3. **超时控制**:`WaitOne(int millisecondsTimeout)` 可设置最长等待时间,避免永久阻塞。 --- #### **5. 典型应用场景** - 主线程等待多个子线程初始化完成。 - 批量任务的同步启动(如性能测试中的并发请求)。 - 资源池的协调管理(如数据库连接池)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值