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

深圳做自适应网站制作无锡网站营销公司简介

深圳做自适应网站制作,无锡网站营销公司简介,医疗网站怎么做推广,中山网站建设找阿 n 2总目录 前言 ManualResetEvent 是 C# 中用于线程同步的核心类之一,位于 System.Threading 命名空间下。它的核心功能是通过信号机制控制线程的执行顺序,允许一个或多个线程等待某个信号后再继续运行。与 AutoResetEvent 不同,ManualResetEve…

总目录


前言

ManualResetEvent 是 C# 中用于线程同步的核心类之一,位于 System.Threading 命名空间下。它的核心功能是通过信号机制控制线程的执行顺序,允许一个或多个线程等待某个信号后再继续运行。与 AutoResetEvent 不同,ManualResetEvent 在被触发后会保持信号状态,直到显式地调用 Reset() 方法将其重置为非信号状态。这种特性使得它适用于需要广播多个线程的场景。


一、核心概念

  • 作用:通过信号机制控制线程的执行,允许一个或多个线程等待某个事件完成。
  • 信号状态
    • 有信号(Signaled):所有调用 WaitOne() 的线程不会被阻塞。
    • 无信号(Non-signaled):所有调用 WaitOne() 的线程会被阻塞,直到调用 Set()
  • 手动重置
    • 调用 Set() 后,事件保持有信号状态,需显式调用 Reset() 才能恢复无信号状态。
    • 意味着可以释放多个等待的线程。

本文中所描述的 有信号状态、终止状态、触发状态 意义相同,都是同一种状态的不同名称

二、基本用法

1. 构造函数

var manualEvent = new ManualResetEvent(initialState: false); // 初始无信号
  • initialState:初始化是否为有信号状态(true 表示有信号/或称 已触发,则线程一开始是无需等待信号的)。

2. 关键方法

方法作用
Set()将事件设为有信号状态,释放所有等待线程。
Reset()将事件设为无信号状态,后续的 WaitOne() 会阻塞。
WaitOne()阻塞当前线程,直到事件变为有信号状态。可以指定超时时间
Dispose()释放资源(继承自 WaitHandle)。

三、 示例

示例 1:单线程等待事件

using System.Threading;class Program
{static ManualResetEvent manualEvent = new ManualResetEvent(false);static void Main(){Thread worker = new Thread(DoWork);worker.Start();// 主线程触发信号Thread.Sleep(2000);Console.WriteLine("主线程发送信号");manualEvent.Set(); // 释放工作线程}static void DoWork(){Console.WriteLine("工作线程等待信号...");manualEvent.WaitOne(); // 阻塞直到信号触发Console.WriteLine("工作线程继续执行");}
}

输出

工作线程等待信号...
主线程发送信号
工作线程继续执行

示例 2:广播多个线程

static ManualResetEvent manualEvent = new ManualResetEvent(false);static void Main()
{// 启动3个等待线程for (int i = 0; i < 3; i++){new Thread(() => {manualEvent.WaitOne();Console.WriteLine($"线程 {Thread.CurrentThread.ManagedThreadId} 被唤醒");}).Start();}// 主线程触发广播Thread.Sleep(2000);manualEvent.Set(); // 所有等待线程同时释放manualEvent.Reset(); // 重置为无信号,后续新线程需要重新等待
}

输出

线程 4 被唤醒
线程 5 被唤醒
线程 6 被唤醒

四、与 AutoResetEvent 的区别

1. 区别

特性ManualResetEventAutoResetEvent
重置方式需显式调用 Reset()调用 Set() 后自动重置
唤醒线程数量唤醒所有等待线程每次 Set() 仅唤醒一个线程
适用场景广播通知(如初始化完成、批量任务开始)严格交替执行(如生产者-消费者模型)

2. 示例

  • AutoResetEvent 示例
class Program
{// 线程通知private static AutoResetEvent resetEvent = new AutoResetEvent(false);static void Main(string[] args){// 创建线程Thread worker = new Thread(DoWork);worker.Start();// 用于不断向另一个线程发送信号while (true){Console.ReadKey();resetEvent.Set();           // 按下任意键,将事件设为有信号状态,释放等待线程。}}public static void DoWork(){Console.WriteLine("① 等待中,请发出信号允许我运行");resetEvent.WaitOne();Console.WriteLine("② 等待中,请发出信号允许我运行");resetEvent.WaitOne();Console.WriteLine("③ 等待中,请发出信号允许我运行");// ...Console.WriteLine("线程结束");}
}

输出:按下任意键,按一下输出一下内容

① 等待中,请发出信号允许我运行
② 等待中,请发出信号允许我运行
③ 等待中,请发出信号允许我运行
线程结束
  • ManualResetEvent 示例
class Program
{private static ManualResetEvent resetEvent = new ManualResetEvent(false);static void Main(string[] args){// 创建线程Thread worker = new Thread(DoWork);worker.Start();// 用于不断向另一个线程发送信号while (true){Console.ReadKey();resetEvent.Set();          // 按下任意键,将事件设为有信号状态,释放【所有】等待线程。}}public static void DoWork(){Console.WriteLine("等待中,请发出信号允许我运行");resetEvent.WaitOne();// 后面的都无效,线程会直接跳过而无需等待Console.WriteLine("等待中,请发出信号允许我运行");resetEvent.WaitOne();Console.WriteLine("等待中,请发出信号允许我运行");resetEvent.WaitOne();Console.WriteLine("等待中,请发出信号允许我运行");resetEvent.WaitOne();Console.WriteLine("等待中,请发出信号允许我运行");resetEvent.WaitOne();Console.WriteLine("等待中,请发出信号允许我运行");resetEvent.WaitOne();Console.WriteLine("线程结束");}
}

输出:按下任意键,直接输出所有内容

等待中,请发出信号允许我运行
等待中,请发出信号允许我运行
等待中,请发出信号允许我运行
等待中,请发出信号允许我运行
等待中,请发出信号允许我运行
等待中,请发出信号允许我运行
线程结束
  • AutoResetEventWaitOne() 方法等待信号完毕后,会自动重置为无信号状态,相当于高速收费站自动闸门,一辆车过去后,机器自动关闸。

  • ManualResetEvent 相当于人工闸门,打开后需要人工关闭闸门,不然的话闸门会一直处于打开状态。

  • ManualResetEvent 主要用于更加灵活的线程信号传递场景。

五、高级用法

1. 超时等待

bool signaled = manualEvent.WaitOne(TimeSpan.FromSeconds(3));
if (!signaled)
{Console.WriteLine("等待超时");
}

六、注意事项

1. 资源释放

  • 使用 Dispose()using 块释放资源,避免句柄泄漏。
using (var manualEvent = new ManualResetEvent(false))
{// 使用 manualEvent
}

2. 避免死锁

  • 确保 Set()Reset() 的调用逻辑合理,避免线程永久阻塞。
  • 示例:忘记调用 Set()Reset()

3. 线程安全

  • 多线程环境下,确保对 Set()Reset() 的调用是线程安全的。

七、替代方案

  • ManualResetEventSlim:轻量级版本,性能更高(适合短期等待)。
  • Semaphore/SemaphoreSlim:控制并发线程数量。
  • TaskCompletionSource:基于任务的异步模式(TAP)。

八、常见问题

1. 问题:忘记调用 Reset()

  • 现象Set() 后事件保持有信号状态,后续所有 WaitOne() 直接通过。
  • 解决:在需要重新阻塞线程前调用 Reset()

2. 问题:多次调用 Set()

  • 现象:无影响,事件已处于有信号状态时,Set() 不会改变状态。

结语

回到目录页:C#/.NET 知识汇总
希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。


参考资料:
ManualResetEvent的使用
C# ManualResetEvent 类的用法
C#学习(二十八)——ManualResetEvent的理解和使用
手动线程通知 ManualResetEvent

http://www.yayakq.cn/news/168050/

相关文章:

  • 建站之星导出网站万网虚拟主机免费空间
  • 文章网站的一级二级怎么做湖南省建设厅网站官网
  • 网站建设需要要多少钱网站经常修改好不好
  • 沈阳哪有做网站的网站建设需要云主机吗
  • 网站设计示例网站设计建设
  • 网站建设与代运营产品介绍建设企业和施工企业
  • 汽车网站建设制作费用优秀企业网站建设哪家服务好
  • 石家庄网站定做网站建设douyanet
  • 温州外贸网站设计网站降权不收录
  • 站长seo综合查询手机app注册免费下载
  • 网站建设的公司工作室大美互助app
  • 广州营销型网站建设哪家好国外空间网站源码
  • 建筑图集网站phpcmsv9手机网站开发
  • 贝斯特专业网站中英文企业网站源码
  • 什么网站可以做外链sem竞价账户托管
  • 邢台网站建设制作成都网站排名提升
  • 律师事务所网站模板关联词有哪些关系
  • 四海网络网站建设自己做简单会员管理系统
  • 网站建设工具公司wordpress mysql缓存
  • 高大上网站欣赏wordpress 修改后台
  • 学校网站建设背景威联通 wordpress
  • 网站开发超速云网页是什么
  • 网站代码在哪里写免费软件大全下载安装
  • 做购物网站的步骤北流网站
  • 网站建设营销的公司wordpress帐号
  • e时代网站制作网页设计与网站规划
  • 建设一个网站wordpress 中文标签
  • wap视频网站淘宝seo是指
  • 手机做炫光头像图的网站网站做推广赚钱项目
  • 深州网站东莞网站建设十大品牌