0

0

C# Monitor类使用方法 C# Monitor.Wait和Pulse如何实现线程通信

畫卷琴夢

畫卷琴夢

发布时间:2026-03-08 12:12:11

|

558人浏览过

|

来源于php中文网

原创

monitor.wait 必须在 lock 块内调用,否则抛出 synchronizationlockexception;它会释放锁并挂起线程,唤醒后需重新竞争锁;必须用 while 循环检查条件,配合状态变量和 pulse/pulseall 正确使用。

c# monitor类使用方法 c# monitor.wait和pulse如何实现线程通信

Monitor.Wait 必须在 lock 块内调用,否则抛出 SynchronizationLockException

这是最常踩的坑:Monitor.Wait 不是“随便等一下”,它本质是释放当前线程持有的锁、挂起自己,并等待被唤醒。如果没持有锁就调用,运行时直接报 SynchronizationLockException

正确姿势是:先用 lock(obj)Monitor.Enter 获取锁,再调用 Monitor.Wait;它内部会自动释放该锁,并在被 PulsePulseAll 唤醒后、重新竞争获取同一把锁——注意,不是立刻恢复执行,而是要再次抢到锁才能继续往下走。

  • 错误示例:Monitor.Wait(someObj) 单独写在外面 → 立即崩溃
  • 正确结构:lock (someObj) { Monitor.Wait(someObj); }
  • 若用 Monitor.Enter 手动加锁,必须配对 try/finally + Monitor.Exit,否则异常时锁不释放

Monitor.Pulse 只唤醒一个等待线程,且只对“已进入 Wait 队列”的线程有效

Monitor.Pulse 不是广播,也不保证唤醒谁。它只从当前对象的 wait queue 中挑一个线程(通常是等待最久的那个)移到 ready queue,让其有机会重新竞争锁。关键点在于:“Pulse 之前没有 Wait” = 白脉冲,什么也不会发生。

典型误用是生产者先 Pulse、消费者后 Wait,结果消费者永远卡住。因为 Pulse 发生时没人等着,信号丢失了。

Veed AI Voice Generator
Veed AI Voice Generator

Veed推出的AI语音生成器

下载
  • 必须严格遵循“先 Wait,后 Pulse”顺序(或至少确保 Wait 已启动)
  • 若需唤醒所有等待者,改用 Monitor.PulseAll,比如多个消费者争抢同一资源
  • Pulse 调用本身不要求持有锁?错!它也必须在 lock 块内,否则同样抛 SynchronizationLockException

Wait/Pulse 组合常用于“生产者-消费者”场景,但需配合状态变量判断条件

Monitor.WaitPulse 本身不传递数据、也不校验业务逻辑。它们只是线程调度开关,真正决定“该不该等”“该不该醒”的,是你自己维护的状态变量(如队列是否为空、缓冲区是否满)。

常见错误是裸调 Wait,不检查条件,导致虚假唤醒(spurious wakeup)或逻辑错乱。.NET 的 Wait 设计允许唤醒后条件仍未满足,所以必须用 while 循环重检。

lock (queueLock)
{
    while (messageQueue.Count == 0)
    {
        Monitor.Wait(queueLock);
    }
    var msg = messageQueue.Dequeue();
}
  • 永远用 while 包裹 Wait,不用 if
  • 状态变量(如 Count)必须在同一个锁保护下读写,否则有竞态
  • Pulse 方通常在修改完状态后立即调用,例如 EnqueueMonitor.Pulse

Wait 可带超时,避免永久阻塞;但超时返回 false 不代表错误,只是“没等到”

Monitor.Wait(object, int)Monitor.Wait(object, TimeSpan) 允许指定最大等待时间。超时后方法返回 false,线程恢复执行,但锁依然被持有(因为 Wait 是在 lock 块里释放并重入的)。

这适合做轮询、防死锁、或实现带截止时间的任务调度。但要注意:返回 false 是正常流程分支,不是异常,不应直接 throw。

  • 超时后需手动检查状态是否满足,不满足可 continue 等下一轮,或 break 处理超时逻辑
  • 超时值设太小会导致频繁空转,太大则响应延迟高;建议结合业务容忍度设定
  • 不要在 Wait 超时后忘记处理未完成的业务路径(比如连接未建立就继续发请求)
实际用起来最难的从来不是语法,而是状态同步的边界和唤醒时机的确定——多一个 Pulse、少一个 Wait、漏一次状态检查,都可能让线程卡在某个角落,日志里还看不出明显错误。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
if什么意思
if什么意思

if的意思是“如果”的条件。它是一个用于引导条件语句的关键词,用于根据特定条件的真假情况来执行不同的代码块。本专题提供if什么意思的相关文章,供大家免费阅读。

846

2023.08.22

counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

203

2023.11.20

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

105

2023.09.25

java中break的作用
java中break的作用

本专题整合了java中break的用法教程,阅读专题下面的文章了解更多详细内容。

120

2025.10.15

java break和continue
java break和continue

本专题整合了java break和continue的区别相关内容,阅读专题下面的文章了解更多详细内容。

261

2025.10.24

java break和continue
java break和continue

本专题整合了java break和continue的区别相关内容,阅读专题下面的文章了解更多详细内容。

261

2025.10.24

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

970

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

605

2024.08.29

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

23

2026.03.06

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号