C# ManualResetEvent 与 AutoResetEvent 区别
在多线程开发中,时常用到 ManualResetEvent 与 AutoResetEvent 。 它们如同道路交通中的信号灯。两者之间有什么区别呢?
共同点:
均继承 EventWaitHandle 接口,因此,均具有以下功能:
Reset() //红灯
Set() //绿灯
WaitOne() // 等待信号
不同点:
AutoResetEvent 收到 Set 后 , 一次只能执行一个线程,其它线程继续 WaitOne 。
ManualResetEvent 收到 Set 后,所有处理 WaitOne 状态线程均继续执行。
msdn 提到(如果没有线程 处于WaitOne() 状态,而调用 Set , AutoResetEvent 将保持Set 状态):
调用Set信号AutoResetEvent释放等待线程。 AutoResetEvent 将保持终止状态直到一个等待线程释放,并自动返回到非信号状态。 如果没有线程处于等待状态,状态将无限期地保持已发出信号。
因此通常WatiOne 之前,先 Reset() 一下,清除Set 信号
需要注意的是(两个 Set 调用之间时间较短,第二个 Set 信号可能会丢失,因此连续 Set 调用,中间需要 Sleep 一定时间):
不能保证的每个调用Set方法将释放一个线程。 如果两次调用太靠近在一起,以便第二次调用前释放线程发生,只有一个线程被释放。 就像第二次调用未发生。 此外,如果Set时没有等待的线程调用和AutoResetEvent已终止,则调用不起作用。
有网友说:
AutoResetEvent.Set() = ManualResetEvent.Set() + ManualResetEvent.Reset();
个人理解 ,这只是原理层面含义,实际使用过程中,有差别的,如下示例:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace testManualResetEvent
{class Program{static object objManualResetEvent = new object();static System.Threading.ManualResetEvent manu = new System.Threading.ManualResetEvent(false);//static System.Threading.AutoResetEvent manu = new System.Threading.AutoResetEvent(false);static void Main(string[] args){for (int i = 0; i < 10; i++){System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(() => { Product(); }));t.Start();}manu.Set();manu.Reset();Console.ReadKey();}static void Product(){manu.WaitOne(10000);Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);}}
}
实际执行结果 , 在 执行 set 后 reset 前 ,有多少个线程唤起执行,无法预料:
需要加锁 ,确保一次通过一个线程:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace testManualResetEvent
{class Program{static object objManualResetEvent = new object();static System.Threading.ManualResetEvent manu = new System.Threading.ManualResetEvent(false);//static System.Threading.AutoResetEvent manu = new System.Threading.AutoResetEvent(false);static void Main(string[] args){for (int i = 0; i < 10; i++){System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(() => { Product(); }));t.Start();}manu.Set();//System.Threading.Thread.Sleep(100); //连续 set 需要 sleep//manu.Set();//manu.Reset();//System.Threading.Thread.Sleep(100);//manu.Set();//manu.Reset();Console.ReadKey();}static void Product(){lock (objManualResetEvent){manu.WaitOne(10000);manu.Reset();Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);}}}
}
执行结果:
C# ManualResetEvent 与 AutoResetEvent 区别相关推荐
- c#线程学习之ManualResetEvent和AutoResetEvent的区别!
AutoResetEvent在.Net多线程编程中经常用到.当某个线程调用WaitOne方法后,信号处于发送状态,该线程会得到信号, 程序就会继续向下执行,否则就等待.而且 AutoResetEven ...
- .Net 中 ManualResetEvent 和 AutoResetEvent 的区别
在 .Net 多线程中可以使用 ManualResetEvent 和 AutoResetEvent 来协调不同的线程的运行.文档中说这两个类都可以通过 set 方法释放信号,等待信号的线程可以通过捕获 ...
- C#使用ManualResetEvent和AutoResetEvent处理线程通信
示例 两个线程交替输出"1 a 2 b 3 c 4 d 5 ....." 代码 //利用ManualResetEvent和AutoResetEvent交替输出"1 a 2 ...
- C# 总结ManualResetEvent与AutoResetEvent【一】
C# 总结ManualResetEvent与AutoResetEvent[一] ManualResetEvent: ManualResetEvent 允许线程通过发信号互相通信.通常,此通信涉及一个线 ...
- ManualResetEvent,AutoResetEvent 学习
AutoResetEvent :通知正在等待的线程已发生事件.无法继承此类. ManualResetEvent:通知一个或多个正在等待的线程已发生事件.无法继承此类. using System; us ...
- 多线程间通信之AutoResetEvent和ManualResetEvent的原理分析
AutoResetEvent 允许线程通过发信号互相通信. 通常,当线程需要独占访问资源时使用该类. 线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号. 如果 AutoRe ...
- 【深度好文】多线程之WaitHandle--派生EventWaitHandle事件构造-》AutoResetEvent、ManualResetEvent...
AutoResetEvent/ManualResetEvent 都是继承自 EventWaitHandle ,EventWaitHandle继承自WaitHandle. 在讨论这个问题之前,我们先了解 ...
- c# AutoResetEvent和ManualResetEvent
网上有很多AutoResetEvent和ManualResetEvent的详细介绍,在这里不做过多详细的解释,写下自己的一点心得留作备忘. AutoResetEvent和ManualResetEven ...
- C# 线程的挂起与唤醒 (AutoResetEvent,ManualResetEvent)
如果说C#和C++有什么不同,博主不得不说,对于异步的支持程度是C#的一一个伟大的进步. 其实早期的C++都没有异步,并发的概念.博主第一次使用C++创建异步程序的时候,是使用boost库的内容进行实 ...
- C# ManualResetEvent
原文链接 http://dotnetpattern.com/threading-manualresetevent ManualResetEvent 和AutoResetEvent一样,是另外一种.NE ...
最新文章
- 【问题帖】压缩图片大小至指定Kb以下
- 【Java 泛型】泛型用法 ( 泛型编译期擦除 | 上界通配符 <? extends T> | 下界通配符 <? super T> )
- SAP S/4HANA生产排期scheduling profile配置
- SharePoint 2013 Farm 安装指南——Least Privilege
- 术中导航_密码术中的计数器(CTR)模式
- freertos内核 任务定义与切换 原理分析
- QT Core | 信号槽03 - 自定义信号与槽
- vue echarts动态数据定时刷新
- 【OpenCV】角点检测:Harris角点及Shi-Tomasi角点检测
- 1.1.2 Greedy Gift Givers 贪婪的送礼者
- sql server2008如何修改mac地址_QCC304x/QCC514x:修改蓝牙MAC地址及名称
- 222.完全二叉树的节点个数
- oracle的多个exclude,记录一下expdp exclude的用法
- python做波士顿房价预测
- 怎样才能彻底地删除多余输入法软件
- HtmlUnit入门教程
- Python3 open()函数
- tikz包 安装_TikZ: LaTeX绘图包
- android多渠道打包
- 色温(光源,环境,季节)
热门文章
- 威纶和s7200通讯线_S7-200PLC和威纶通触摸屏MODBUS RTU协议通讯实例
- android桌面半透明,Android仿Iphone屏幕底部弹出半透明PopupWindow效果
- excel常用功能记录(不断更新)
- UE4游戏提取的通用步骤(21_9_8)
- QCC3040---Application启动流程
- 接口测试用例设计方法
- 中国省-市-县(区)三级城市数据(json和数组)
- HTML+CSS静态页面`西安旅游网站设计——西安旅游(7页) 大学生旅游网页作品 出行网页设计作业模板 学生游玩网页制作源代码下载
- 快速对二叉树和前中后序遍历的相互转化
- MessageBox的用法