AutoResetEvent/ManualResetEvent 的简单理解与运用
AutoResetEvent 和 ManualResetEvent 只是构造函数包装器 它们唯一要做的就是使用EventResetMode.AutoReset或EventResetMode.ManualReset从EventWaitHandle调用构造函数.
三.常用方法
Reset ()
将事件状态设置为非终止状态,导致线程阻止;如果该操作成功,则返回true;否则,返回false.
Set ()
将事件状态设置为终止状态,允许一个或多个等待线程继续;如果该操作成功,则返回true;否则,返回false.
注:不能保证每次调用 Set 该方法都会释放线程。 如果两个调用太接近,以便第二次调用在释放线程之前发生,则只释放一个线程。 就好像第二次调用没有发生一样。 此外,如果没有 Set 等待的线程且 AutoResetEvent 已发出信号,则调用无效。
WaitOne()
阻止当前线程,直到收到信号.
WaitOne(TimeSpan, Boolean)
阻止当前线程,直到当前实例收到信号,使用 TimeSpan 度量时间间隔并指定是否在等待之前退出同步域.
区别
.AutoResetEvent 和 ManualResetEvent都继承自EventWaitHandle.
2.AutoResetEvent 收到 Set 后 , 一次只能执行一个线程,其它线程继续 WaitOne .
ManualResetEvent 收到 Set 后,所有处理 WaitOne 状态线程均继续执行.
class Program { static AutoResetEvent are; static void FinishOrTimeOut(object obj) { are.WaitOne(); for(int i = 0; i < 500; i++) { Console.Write(i + " "); } } static void FinishOrTimeOut1(object obj) { are.WaitOne(); for(int i = 500; i < 1000; i++) { Console.Write(i + " "); } } static void Main(string[] args) { using(are = new AutoResetEvent(false)) { Thread thread = new Thread(FinishOrTimeOut); thread.Start(); Thread thread1 = new Thread(FinishOrTimeOut1); thread1.Start(); Console.WriteLine("-----"); are.Set(); Console.ReadLine(); } } }
ManualResetEvent
class Program { static ManualResetEvent are; static void FinishOrTimeOut(object obj) { are.WaitOne(); for(int i = 0; i < 500; i++) { Console.Write(i + " "); } } static void FinishOrTimeOut1(object obj) { are.WaitOne(); for(int i = 500; i < 1000; i++) { Console.Write(i + " "); } } static void Main(string[] args) { using(are = new ManualResetEvent(false)) { Thread thread = new Thread(FinishOrTimeOut); thread.Start(); Thread thread1 = new Thread(FinishOrTimeOut1); thread1.Start(); Console.WriteLine("-----"); are.Set(); Console.ReadLine(); } } }
AutoResetEvent 自动Reset().
ManualResetEvent 手动调用Reset().
class Program { static ManualResetEvent are; //未被阻塞 static void FinishOrTimeOut(object obj) { for(int i = 0; i < 500; i++) { Console.Write(i + " "); } } //被阻塞 static void FinishOrTimeOut1(object obj) { are.WaitOne(); for(int i = 500; i < 1000; i++) { Console.Write(i + " "); } } //被阻塞 static void FinishOrTimeOut2(object obj) { are.WaitOne(); for(int i = 1000; i < 1500; i++) { Console.Write(i + " "); } } static void Main(string[] args) { using(are = new ManualResetEvent(false)) { Thread thread = new Thread(FinishOrTimeOut); thread.Start(); Thread thread1 = new Thread(FinishOrTimeOut1); thread1.Start(); are.Set(); Console.WriteLine("-----"); Thread.Sleep(1000); Thread thread2 = new Thread(FinishOrTimeOut2); thread2.Start(); Console.ReadLine(); } } }
class Program { static ManualResetEvent are; //未被阻塞 static void FinishOrTimeOut(object obj) { for(int i = 0; i < 500; i++) { Console.Write(i + " "); } } //被阻塞 static void FinishOrTimeOut1(object obj) { are.WaitOne(); for(int i = 500; i < 1000; i++) { Console.Write(i + " "); } //手动关闭 are.Reset(); } //被阻塞 static void FinishOrTimeOut2(object obj) { are.WaitOne(); for(int i = 1000; i < 1500; i++) { Console.Write(i + " "); } } static void Main(string[] args) { using(are = new ManualResetEvent(false)) { Thread thread = new Thread(FinishOrTimeOut); thread.Start(); Thread thread1 = new Thread(FinishOrTimeOut1); thread1.Start(); are.Set(); Console.WriteLine("-----"); Thread.Sleep(1000); Thread thread2 = new Thread(FinishOrTimeOut2); thread2.Start(); Console.ReadLine(); } } }
1.Monitor是一个静态类,没有父类.
AutoResetEvent 是密封类,继承EventWaitHandle->WaitHandle->MarshalByRefObject .
2.AutoResetEvent是传统的Win32 同步方式的封装,和使用传统的方式没有太大的区别,互斥体,信号量,事件等都是系统资源,有一定的性能开销,比Monitor性能要差一些.
3.Monitor只能在单一进程内使用.
而传统的同步机制互斥体:Mutex 信号量:Semaphore/SemaphoreSlim
事件:ManualResetEventSlim/CountdownEvent/AutoResetEvent/ManualResetEvent
是可以对多个进程进行同步的!(利用基类EventWaitHandle中的静态方法OpenExisting)
4.使用Monitor时可以保护资源.
AutoResetEvent 只是通知事情发生.
————————————————
版权声明:本文为CSDN博主「一梭键盘任平生」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/SmillCool/article/details/127241363