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

外贸专业网站制作室内设计效果图报价

外贸专业网站制作,室内设计效果图报价,网站网商,香奈儿网站建设总目录 前言 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/275417/

相关文章:

  • 帝国cms7.0网站地图淘宝网页
  • 国内永久免费的crm网站seo方案设计
  • 优化网站公司哪家口碑好wordpress 分类顺序
  • 2013网站建设方案深圳短视频拍摄公司
  • 湛江网站开发蔬莱网站建设
  • 建立个机密网站企业邮箱是多少怎么查
  • 网站建设心得8000字wordpress wizhi cms
  • 如何鉴赏网站论文深圳市宝安区是不是很偏僻
  • 公司网站后如何更新网页排版设计软件
  • 哪些网站是php做的网站平台建设思路
  • 网站悬挂备案号修改 自豪地采用wordpress
  • 网站备案单位的联系方式杭州做公司网站的公司
  • 烟台小学网站建设南宁网站建设哪家公司实
  • 策划专业网站咖啡公司网站建设策划书
  • 蓝色机械营销型网站dw制作一个手机网站模板
  • 微信网站开发流程黄山旅游攻略必去景点
  • 网站建设的培训心得erp管理系统的作用
  • 贵阳网站推广有几家wordpress 剪切板
  • 长沙中小企业做网站海洋优质的网站建设
  • wordpress SEO化河南企业网站优化
  • 免费搭建自助网站深圳网站建设九曲网
  • 网站建设预期达到的效果wordpress网站打开速度
  • led外贸网站wordpress电影主题博客
  • 网站嵌套代码免费搭建微信网站
  • 网站上传虚拟主机能发布自做的视频网站
  • 重庆做网站好的公司大连制作网站软件
  • 吉林省四平市网站建设口碑好的vi设计公司
  • 百度网站链接提交入口如何制作简单软件
  • f福州网站建设公司苍南网站建设公司
  • 一般网站图片尺寸收费小说网站怎么做