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


 

posted @ 2023-03-26 13:35  桃花雪  阅读(120)  评论(0编辑  收藏  举报